// IA32Interpreter.cpp
// Implement the class IA32Interpreter

#include "crossbit/common.h"
#include "crossbit/VInst.h"
#include "crossbit/ELFMemoryImage.h"
#include "arch/ia32/IA32VBasicBlockBuilder.h"
#include "arch/ia32/IA32Interpreter.h"
#include "arch/ia32/IA32Syscall.h"
#include <iostream>
#include <cmath>
#include "disasm.h"

namespace crossbit{
#define t1 41
#define t2 42
#define t3 43
#define t4 44
#define t5 45

#define VREG(a)    ((a) + 1)

#define NEAX 0

#define SR  8

#define NCF 15
#define NOF 16
#define NSF 17
#define NZF 18
#define NAF 19
#define NPF 20
#define NDF 21

#define	SEG_BASE    26
#define TTT 27

#define MODRMREG 29
#define TEMPREG1 30
#define TEMPREG2 31
#define TEMPREG3 33
#define TEMPREG4 34
#define TEMPREG5 35

    static BlockSize op_size = WORD;

#define IA32GET(a,b)	GET((a),op_size,(b))
#define IA32PUT(a,b)	PUT((a),op_size,(b))

    IA32Syscall* syscall;

    //add by chuchao
    volatile int hasRep = false;
    volatile int segOver = false;
    volatile XTRegNum segReg;

    volatile int repFlag = 0;
    volatile int eraseRep = 0;
    volatile unsigned int top = 0;

    volatile int curNext = 0;

/**
 * It will be only used in the set flags function to improve performance.
 */
 Word* _regs = 0;


    void set_seg_base(ProcessorState *state,int gs)
    {
        // empty now
    }

    void cmpxchg(ProcessorState *state,int reg, int rorm)
    {
	int r = state->reg(reg);
	int a = state->reg(NEAX);
	int b;
	if( rorm < 100 ) // NEED TODO
	    b = state->reg(rorm);
	else
	    b = *(int*)(rorm);

	if( a == b )
	{
	    state->put(NZF, 1);
	    //r[NZF]=1;
	    *(int*)rorm = r;
	}
	else
	{
	    state->put(NZF,0);
	    state->put(NEAX, b);
	}
    }
	
	void do_cmpxchg_one(int reg)
	{
//			printf("Hello here mem_one \n");
			_regs[NZF] = 1;
	}
	void do_cmpxchg_zero(int reg)
	{
//			printf("Hello here mem_zero \n");
			_regs[NZF] = 0;
	}

    void syscallWrapper()
    {
	       syscall->operator()();
    }

    void initializeSyscall(IA32Syscall* s)
    {
	       syscall = s;
    }

    void set_flags_adcl(int a, int b, int c)
    {
	int tmp = a + b + c;

	if (c == 0)
	{
            if ( (unsigned)tmp < (unsigned)a )
	    {
	        _regs[NCF]=1;
	    }
  	    else
	    {
	        _regs[NCF] = 0;
	    }
	}
	else
	{
	    if ( (unsigned)tmp <= (unsigned)a )
	    {
	        _regs[NCF]=1;
	    }
  	    else
	    {
	        _regs[NCF] = 0;
	    }
	}
	
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( (signed)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ( c == 0)
	{
	    if ( ((a < 0) == (b < 0)) && ((tmp < 0) != (a < 0) ))
	    {
	        _regs[NOF]=1;
	    }
	    else
	    {
	        _regs[NOF] = 0;
	    }
	}
	else
	{
	    int d = a + b;

	    if ( ((a < 0) == (b < 0)) && ((d < 0) != (a < 0) ))
	    {
	        _regs[NOF]=1;
	    }
	    else
	    {
		int f = d + c;
		if ( d > 0 && f < 0 )
		    _regs[NOF] = 1;
		else
		    _regs[NOF] = 0;
	    }
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_addl(int a, int b)
    {
	int tmp = a + b;
	if ( (unsigned)tmp < (unsigned)a )
	{
	    _regs[NCF]=1;
	}
	else
	{
	    _regs[NCF] = 0;
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( (signed)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	if ( ((a < 0) == (b < 0)) && ((tmp < 0) != (a < 0) ))
	{
	    _regs[NOF]=1;
	}
	else
	{
	    _regs[NOF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_addw(int a,int b)
    {
	short c = (short)( a & 0xffff);
	short d = (short)( b & 0xffff);
	short tmp = c + d;
	if ( (unsigned short)tmp < (unsigned short)c )
	{
	    _regs[NCF]=1;
	}
	else
	{
	    _regs[NCF] = 0;
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	if ( (c < 0 == d < 0) && (tmp < 0 != c < 0 ))
	{
	    _regs[NOF]=1;
	}
	else
	{
	    _regs[NOF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_addb(int a, int b)
    {
	a = a & 0xff;
	b = b & 0xff;
	int tmp = a + b;
	tmp = tmp & 0xff;

	if ( (unsigned)tmp < (unsigned)a )
	{
	    _regs[NCF]=1;
	}
	else
	{
	    _regs[NCF] = 0;
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp&0x80) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	if ( ((a&0x80 != 0) == (b&0x80 != 0)) && ((tmp &0x80!=0) != (a&0x80 !=0)))
	{
	    _regs[NOF]=1;
	}
	else
	{
	    _regs[NOF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

void createEFLAGS(int regNum)
{
	XTUint16 flag = 0;
	unsigned ncf = _regs[NCF], nof = _regs[NOF], nsf = _regs[NSF],
			nzf = _regs[NZF], naf = _regs[NAF], npf = _regs[NPF], ndf = _regs[NDF];
			
	flag = flag | (ncf) | (nzf<<6) | (nsf<<7) | (nof <<11);

	_regs[regNum] = flag;

}
	void set_flags_popf(int a)
	{
		_regs[NCF] = a & 1;
		_regs[NZF] = a >> 6 & 1;
		_regs[NSF] = a >> 7 & 1;
		_regs[NOF] = a >> 11 & 1;
	}

    void set_flags_subl(int a, int b)
    {
	int tmp = a - b;
	if ( (unsigned)a < (unsigned)b )
	{
	    _regs[NCF] = 1;
	}
	else
	{
	    _regs[NCF] = 0;
	}	

	if ( tmp == 0 )
	{
	    _regs[NZF] = 1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( (signed)tmp < 0 )
	{
	    _regs[NSF] = 1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((a < 0 && b > 0) || (a > 0 && b < 0))
	{
	    if ((tmp > 0 == b > 0) || (tmp < 0 == b < 0))
		_regs[NOF] = 1;
	    else
		_regs[NOF] = 0;
	}
	else
	{
	    _regs[NOF] = 0;
	}
    }

    void set_flags_subw(int a, int b)
    {
	short c = (short) (a & 0xffff);
	short d = (short) (b & 0xffff);

	short tmp = c - d;
	if ( (unsigned short)c < (unsigned short)d )
	{
	    _regs[NCF]=1;
	}
	else
	{
	    _regs[NCF] = 0;
	}	

	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}

	if ( (signed short)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((c < 0 && d > 0 && tmp > 0) || (c > 0 && d < 0 && tmp < 0))
	{
	    _regs[NOF] = 1;
	}
	else
	{
	    _regs[NOF] = 0;
	}

	// TODO AP, PF should be set
    }

    void set_flags_subb(int a, int b)
    {
	a &= 0xff;
	b &= 0xff;

	int tmp = a - b;
	if ( (unsigned)a < (unsigned)b )
	{
	    _regs[NCF]=1;
	}
	else
	{
	    _regs[NCF] = 0;
	}	
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp & 0x80) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((((a&0x80)!=0) && ((b&0x80)==0)) || (((a&0x80)==0) && ((b&0x80)!=0)))
	{
	    if ( (((tmp&0x80)==0) == ((b&0x80)==0)) || (((tmp&0x80)!=0) == ((b&0x80)!=0)))
	    {
		_regs[NOF] =  1;
	    }
	    else
	    {
		_regs[NOF] = 0;
	    }
	}
	else
	{
	    _regs[NOF] = 0;
	}
    }

    void set_flags_decl1(int a)
    {
	int tmp = a - 1;
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( (signed)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if (a < 0 && tmp > 0)
	{
	    _regs[NOF]=1;
	}
	else
	{
	    _regs[NOF] = 0;
	}
    }

    void set_flags_decw1(int a)
    {
	short c = (short) ( a & 0xffff);
	short d = (short) (1);

	short tmp = c - d;
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( (signed short)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((c < 0 && d > 0) || (c > 0 && d < 0))
	{
	    if ((tmp > 0 == d > 0) || (tmp < 0 == d < 0))
		_regs[NOF]=1;
	    else
		_regs[NOF] = 0;
	}
	else
	{
	    _regs[NOF] = 0;
	}
    }

    void set_flags_decb1(int a)
    {
	a = (a & 0xff);

	int b = 1;
	int tmp = a - b;
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}

	if ((tmp & 0x80) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((((a&0x80)!=0) && ((b&0x80)==0)) || (((a&0x80)==0) && ((b&0x80)!=0)))
	{
	    if ( (((tmp&0x80)==0) == ((b&0x80)==0)) || (((tmp&0x80)!=0) == ((b&0x80)!=0)))
	    {
		_regs[NOF] = 1;
	    }
	    else
		_regs[NOF] = 0;
	}
	else
	{
	    _regs[NOF] = 0;
	}
    }

    void set_flags_andl(int a)
    {
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( a == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (signed)a < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_andw(int a)
    {
	a = a & 0xffff;
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( a == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (a & 0x8000) != 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_andb(int a)
    {
	a = a & 0xff;
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( a == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (a & 0x80) != 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_xorl(int a)
    {
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( a == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (signed)a < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	//TODO:set PF according to the result
	//TODO:AF is undefined
    }

    void set_flags_xorw(int a)
    {
	short b = (short) (a & 0xffff);
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( b == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if (b < 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	//TODO:set PF according to the result
	//TODO:AF is undefined
    }

    void set_flags_xorb(int a)
    {
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( (a&0xff) == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (a&0x80) != 0)
	{
	   _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	//TODO:set PF according to the result
	//TODO:AF is undefined
    }

    void set_flags_testl(int a)
    {
	_regs[NCF] = 0;
	_regs[NOF] = 0;

	if (a == 0)
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ((signed)a < 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	//TODO:set PF according to the result
	//TODO:AF is undefined
    }

    void set_flags_testb(int a)
    {
	_regs[NCF] = 0;
	_regs[NOF] = 0;
	if ( (a&0xff) == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ((a&0x80) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	//TODO:set PF according to the result
	//TODO:AF is undefined
    }

    void set_flags_testw(int a)
    {
	_regs[NCF] = 0;
	_regs[NOF] = 0;

	if ( (a&0xffff) == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ((a&0x8000) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	//TODO:set PF according to the result
	//TODO:AF is undefined
    }

    void set_flags_rorl(unsigned int a, unsigned int b)
    {
	unsigned int c = ((a << (32-b)) & (a >> b));
	unsigned int d = ((c>>31) & 0x1);
	_regs[NCF] = d;

	if ( b == 1)
	{
	    unsigned e = ((c>>30) & 0x1);
	    
	    if( (d==1&&e==0) || (d==0&&e==1))
		_regs[NOF] = 1;
	    else
		_regs[NOF] = 0;
	}
    }

    void set_flags_rorw(unsigned int a, unsigned int b)
    {
	a = ( a & 0xffff);
	b = ( b & 0xffff);

	unsigned int c = ((a << (16-b)) & (a >> b));
	unsigned int d = ((c>>15) & 0x1);
	_regs[NCF] = d;

	if ( b == 1)
	{
	    unsigned e = ((c>>14) & 0x1);
	    
	    if( (d==1&&e==0) || (d==0&&e==1))
		_regs[NOF] = 1;
	    else
		_regs[NOF] = 0;
	}
    }

    
    void set_flags_roll(int a, int b)
    {
	int c = (a >> ( 32 - b));
	c = ( c & 0x1);

	_regs[NCF] = c;

	if (b == 1)
	{
	    c = (a << b);
	    c = (c >> 31);
	    c = (c & 0x1);

	    if ( (c==1&&_regs[NCF]==0) || (c==0&&_regs[NCF]==1))
	    {
		_regs[NOF] = 1;
	    }
	    else
	    {
		_regs[NOF] = 0;
	    }
	}
    }
    
    void set_flags_shll1(int a, int b)
    {
	int tmp = a << b;

	if (b > 0)
	{
	    _regs[NCF] = (((a << (b-1)) & 0x80000000) != 0);
	}
	if (b == 1)
	{
	    int msb = ((a & 0x80000000) != 0);
	    _regs[NOF] = (msb != _regs[NCF]);
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp&0x80000000) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_shlw(int a,int b)
    {
	a = (a & 0xffff);
	int tmp = a << b;

	if (b > 0)
	{
	    _regs[NCF] = (((a << (b-1)) & 0x8000) != 0);
	}
	if (b == 1)
	{
	    int msb = ((a & 0x8000) != 0);
	    _regs[NOF] = (msb != _regs[NCF]);
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp&0x8000) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_shrl1(int a,int b)
    {
	int tmp = (unsigned)a >> b;

	if ( b > 0 )
	{
	    _regs[NCF] = (((unsigned)a >> (b-1)) & 0x1);
	}
	if (b == 1)
	{
	    _regs[NOF] = ((a & 0x80000000) != 0);
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp & 0x80000000) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_shrw(int a, int b)
    {
	a = (a & 0xffff);
	int tmp = (unsigned)a >> b;

	if ( b > 0 )
	{
	    _regs[NCF] = (((unsigned)a >> (b-1)) & 0x1);
	}
	if (b == 1)
	{
	    _regs[NOF] = ((a & 0x8000) != 0);
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp & 0x8000) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_shrb(int a, int b)
    {
	a = (a & 0xff);
	int tmp = (unsigned)a >> b;

	if ( b > 0 )
	{
	    _regs[NCF] = (((unsigned)a >> (b-1)) & 0x1);
	}
	if (b == 1)
	{
	    _regs[NOF] = ((a & 0x80) != 0);
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((tmp & 0x80) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_sarl1(int a,int b)
    {
	int tmp = a >> b;

	if ( b > 0 )
	{
	    _regs[NCF] = ((a >> (b-1)) & 0x1);
	}
	if (b == 1)
	{
	    _regs[NOF] = 0;
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ( (signed)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_sarw(int a,int b)
    {	
	a = a & 0xffff;
	int tmp = a >> b;

	if ( b > 0 )
	{
	    _regs[NCF] = ((a >> (b-1)) & 0x1);
	}
	if (b == 1)
	{
	    _regs[NOF] = 0;
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((a & 0x8000) != 0)
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }

    void set_flags_sarb(int a,int b)
    {	
	a = a & 0xff;
	int tmp = a >> b;

	if ( b > 0 )
	{
	    _regs[NCF] = ((a >> (b-1)) & 0x1);
	}
	if (b == 1)
	{
	    _regs[NOF] = 0;
	}
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else 
	{
	    _regs[NZF] = 0;
	}
	if ((a & 0x80) != 0)
	{
	    _regs[NSF] = 1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
    }


    void set_flags_imull(int a)
    {	
	if(a == 0)
	{
	    _regs[NCF] = 0;
	    _regs[NOF] = 0;
	}
	else
	{
	    _regs[NCF]=1;
	    _regs[NOF]=1;
	}	
    }

    void set_flags_negl(int a)
    {
	int tmp = ~a + 1;

	if (a == 0)
	    _regs[NCF] = 0;
	else
	    _regs[NCF]=1;

	if (a == BX_MIN_BIT32S - 1) 		
	    _regs[NOF]=1;
	else
	    _regs[NOF] = 0;

	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (signed)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}
	//TODO:set AF,PF according to the result
    }

    void set_flags_shrdl1(int dest, int result, int count)
    {
	_regs[NCF] = ((dest >> (count - 1)) & 0x1);

	if (count == 1)
	{
	    if ((dest > 0) != (result > 0))
		_regs[NOF]=1; 
	    else
		_regs[NOF] = 0;
	}
	else
	{
	    _regs[NOF] = 0;
	}

	if (result == 0)
	    _regs[NZF]=1;
	else
	    _regs[NZF]= 0;

	if (signed(result) < 0)
	    _regs[NSF]=1;
	else
	    _regs[NSF] = 0;
    }

    void set_flags_shldl(int dest, int result, int count)
    {
	_regs[NCF] =((dest << (count - 1)) & 0x80000000); 
	
	if (count == 1)
	{
	   if ((dest > 0) != (result > 0))	    //sign change
		_regs[NOF]=1; 
	    else
		_regs[NOF] = 0;
	}
   	
	if (result == 0)
	    _regs[NZF]=1;
	else
	    _regs[NZF]=0;

	if (signed(result) < 0)
	    _regs[NSF]=1;
	else
	    _regs[NSF]=0;
 
    }
	
	void set_flags_btsl(int a, int b)
	{
		_regs[NCF] = a >> b; 
	}

    void set_flags_incl1(int a)
    {
	int tmp = a + 1;
	if ( tmp == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (signed)tmp < 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((signed)a > 0 && (signed)tmp < 0)
	    _regs[NOF] = 1;
	else
	    _regs[NOF] = 0;
    }

    void set_flags_incb1(int a)
    {
	int tmp = a + 1;
	if ( (tmp&0xff) == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (tmp&0x80) != 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((a&0x80) == 0 && (tmp&0x80) != 0)
	    _regs[NOF] = 1;
	else
	    _regs[NOF] = 0;
    }

    void set_flags_incw1(int a)
    {
	int tmp = a + 1;
	if ( (tmp&0xffff) == 0 )
	{
	    _regs[NZF]=1;
	}
	else
	{
	    _regs[NZF] = 0;
	}

	if ( (tmp&0x8000) != 0 )
	{
	    _regs[NSF]=1;
	}
	else
	{
	    _regs[NSF] = 0;
	}

	if ((a&0x8000) == 0 && (tmp&0x8000) != 0)
	    _regs[NOF] = 1;
	else
	    _regs[NOF] = 0;
    }

    void set_flags_sahf(int a)
    {
	_regs[NCF] = ((a & 0x100) != 0);
	_regs[NPF] = ((a & 0x400) != 0);
	_regs[NAF] = ((a & 0x1000) != 0);
	_regs[NZF] = ((a & 0x4000) != 0);
	_regs[NSF] = ((a & 0x8000) != 0);
    }
}


using namespace crossbit;

XTRegNum IA32Interpreter::resolveModRM(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    BlockSize op_size_save = op_size;
    op_size = WORD;
    switch (insn->mod)
    {
	case 0:
	    switch (insn->rm)
	    {
		//has S-I-B byte
		case 4:
		    if(insn->index == 4)
		    {
			bb->add (IA32GET(insn->base, VREG(insn->base)));
    			//bb->add (MOV(VREG(insn->base), MODRMREG));

			op_size = op_size_save;
			//return MODRMREG;
			return VREG(insn->base);
		    }
		    else
		    {
			bb->add (IA32GET(insn->index, VREG(insn->index)));
			bb->add (LI(insn->scale, TEMPREG1));
			bb->add (SLL(VREG(insn->index), TEMPREG1, MODRMREG));
			if(insn->base == 5)
			{
			    bb->add (ADDI(MODRMREG, insn->displacement.displ32, MODRMREG));
			}
			else
			{
			    bb->add (IA32GET(insn->base, VREG(insn->base)));
			    bb->add (ADD(MODRMREG, VREG(insn->base), MODRMREG));
			}

			op_size = op_size_save;
			return MODRMREG;
		    }
		    break;
		case 5:
		    {
		        bb->add (LI(insn->displacement.displ32, MODRMREG));

			op_size = op_size_save;
			return MODRMREG;
		    }
		default:
		    {
		        bb->add (IA32GET(insn->rm, VREG(insn->rm)));
			//bb->add (MOV(VREG(insn->rm), MODRMREG));

			op_size = op_size_save;
			//return MODRMREG;
			return VREG(insn->rm);
		    }
	    }
	    break;
	case 1:
	case 2:
	    if (insn->rm == 4)				//has S-I-B byte
	    {
		if(insn->index == 4)
		{		//Only (base+disp)
		    bb->add (IA32GET(insn->base, VREG(insn->base)));
		    bb->add (LI(insn->displacement.displ32, MODRMREG));
		    bb->add (ADD(MODRMREG, VREG(insn->base), MODRMREG));

    		    op_size = op_size_save;
    		    return MODRMREG;
		}
		else
		{		// (base + index * scale + disp)
		    bb->add (IA32GET(insn->index, VREG(insn->index)));
		    bb->add (LI((Word)insn->scale, TEMPREG1));
		    bb->add (SLL(VREG(insn->index), TEMPREG1, MODRMREG));
		    bb->add (IA32GET(insn->base, VREG(insn->base)));
		    bb->add (ADD(MODRMREG, VREG(insn->base), MODRMREG));
		    bb->add (ADDI(MODRMREG, insn->displacement.displ32, MODRMREG));

		op_size = op_size_save;
		return MODRMREG;
		}
	    }
	    else
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(insn->displacement.displ32, MODRMREG));
		bb->add (ADD(MODRMREG, VREG(insn->rm), MODRMREG));

		op_size = op_size_save;
		return MODRMREG;
	    }
	    break;
	case 3:
	    {
	        bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		//bb->add (MOV(VREG(insn->rm), MODRMREG));

		op_size = op_size_save;
		//return MODRMREG;
		return VREG(insn->rm);
	    }
    }
    if(segOver)
    {
	op_size = HALFWORD;
	bb->add (IA32GET(segReg, t2));
	bb->add (LI ((Word)state_,t3));
	bb->add (CALL((Word)(&crossbit::set_seg_base),2,t3,t2));
	op_size = WORD;
	bb->add (IA32GET(SEG_BASE, t2));
	bb->add (ADD(t2,t1,t1));
    }
    op_size = op_size_save;

    bb->add (MOV(t1, MODRMREG));
    return MODRMREG;

}

//0f b1 Ia_cmpxchgl_Ed_Gd
void IA32Interpreter::rorm_r_cmpxchgw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	
    if (insn->mod == 3)
    {
		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	bb->add (CMP(EQ, VREG(IA32ProcessorState::EAX), VREG(insn->rm), TEMPREG1));
		bb->add (LOOPN(TEMPREG1, 0, 1));
			bb->add (CALL((Word)(&crossbit::do_cmpxchg_zero), 1, VREG(insn->rm))); 
			bb->add (IA32PUT(insn->rm, VREG(IA32ProcessorState::EAX)));
			bb->add (LOOPN(TEMPREG1, 1, 1));
		bb->add (LABEL(0));
			bb->add (CALL((Word)(&crossbit::do_cmpxchg_one), 1, VREG(insn->rm))); 
			bb->add (IA32PUT(VREG(op->op2.reg), VREG(insn->rm)));
		bb->add (LABEL(1));
	}
    else
    {
		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	XTRegNum t = resolveModRM(insn,op,bb);
		bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
    	bb->add (CMP(EQ, VREG(IA32ProcessorState::EAX), TEMPREG1, TEMPREG2));
		bb->add (LOOPN(TEMPREG2, 0, 1));
			bb->add (CALL((Word)(&crossbit::do_cmpxchg_zero), 1, VREG(insn->rm))); //func do_cmopxchg_zero is to set the ZF = 0;
			bb->add (IA32PUT(TEMPREG1, VREG(IA32ProcessorState::EAX)));
			bb->add (LOOPN(TEMPREG2, 1 ,1));
		bb->add (LABEL(0));	
			bb->add (CALL((Word)(&crossbit::do_cmpxchg_one), 1, VREG(insn->rm))); //func do_cmpxchg_one is to set the ZF = 1 
			bb->add (ST(VREG(op->op2.reg), WORD, t, mm_->map(0)));
		bb->add (LABEL(1));
	}
}

void IA32Interpreter::rorm_r_btsl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
	bb->add (LI(0x1, TEMPREG2));
	bb->add (LI(0x3, TEMPREG3));
	bb->add (LI(0x7, TEMPREG4));
    	
    if (insn->mod == 3)
    {
		printf(" btsl reg not \n" );

    }
    else
    {
//		printf(" hello btsl reg mem \n ");
    XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (SRA(VREG(op->op2.reg), TEMPREG3, TEMPREG5));   // idiv 8; 
	bb->add (AND(VREG(op->op2.reg), TEMPREG4, TEMPREG4));   // mod 8;
	bb->add (ADD(t, TEMPREG5, t));                           // address + idiv/8;
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG3));
	bb->add (SLL(TEMPREG2, TEMPREG4, TEMPREG5));         // 1 << mod 8 
	bb->add (AND(TEMPREG3, TEMPREG5, TEMPREG1));        
	bb->add (OR(TEMPREG3, TEMPREG5, TEMPREG2));          //set 1;
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
	bb->add (CALL((Word)(&crossbit::set_flags_btsl), 2, TEMPREG1, TEMPREG4));  // change the CF value 
	}

}
// A3 

void IA32Interpreter::rorm_r_btl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
	bb->add (LI(0x1, TEMPREG2));
	bb->add (LI(0x3, TEMPREG3));
	bb->add (LI(0x7, TEMPREG4));
    	
    if (insn->mod == 3)
    {
		printf(" btsl reg not \n" );

    }
    else
    {
//		printf(" hello btl reg mem \n ");
    XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (SRA(VREG(op->op2.reg), TEMPREG3, TEMPREG5));   // idiv 8; 
	bb->add (AND(VREG(op->op2.reg), TEMPREG4, TEMPREG4));   // mod 8;
	bb->add (ADD(t, TEMPREG5, t));                           // address + idiv/8;
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG3));
	bb->add (SLL(TEMPREG2, TEMPREG4, TEMPREG5));         // 1 << mod 8 
	bb->add (AND(TEMPREG3, TEMPREG5, TEMPREG1));        
//	bb->add (OR(TEMPREG3, TEMPREG5, TEMPREG2));          //set 1;
//	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
	bb->add (CALL((Word)(&crossbit::set_flags_btsl), 2, TEMPREG1, TEMPREG4));  // change the CF value 
	
	}

}

//A1 Ia_movw_AX_Ow
void IA32Interpreter::AX_Ow_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (LD(TEMPREG1, mm_->map(0), op_size, TEMPREG1));

    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//A3 Ia_movw_Ow_AX 
void IA32Interpreter::Ow_AX_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    //op_size = HALFWORD;
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(op->op1.imm, TEMPREG1));
    bb->add (ST(VREG(IA32ProcessorState::EAX), HALFWORD, TEMPREG1, mm_->map(0)));
}

//89 Ia_movw_Ew_Gw
void IA32Interpreter::rorm_r_movw89(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (ZEXT(VREG(op->op2.reg), HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);

	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (ST(VREG(op->op2.reg), HALFWORD, t, mm_->map(0)));
    }
}

//89 Ia_movl_Ed_Gd
void IA32Interpreter::rorm_r_movl89(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (MOV(VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
       	XTRegNum t = resolveModRM(insn,op,bb);

	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (ST(VREG(op->op2.reg), WORD, t, mm_->map(0)));
    }
}

//8E Ia_movw_Sw_Ew
void IA32Interpreter::r_r_movw8e(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    printf("r_r_movw8e\n");
    XTRegNum t = resolveModRM(insn,op,bb);
    op_size = HALFWORD;
    if (insn->mod == 3)
    {
	//Note:t2 is a XTRegNum(=insn->rm) while mod == 3
	bb->add (IA32GET(insn->rm,t2));
	bb->add (IA32PUT(t2,insn->nnn+SR));//segment register
    }
    else
    {
	printf("should not be here!\n");
    }
}

//8D /r Ia_leal_Gd_Md
void IA32Interpreter::r_m_leal(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (MOV(t, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

//E9 Ia_jmp_Jd
void IA32Interpreter::i_jmpd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("i_jmpd\n");
    //bb->add(JMP(0, op->op1.imm)); 
    insn->ilen = op->op1.imm - curNext;
}

//FF /4  Ia_jmp_Ed
void IA32Interpreter::rorm_jmpd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	bb->add (JMP(VREG(insn->rm), 0)); 
    }
    else
    {
	    XTRegNum t = resolveModRM(insn,op,bb);

	    bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
     bb->add (JMP(TEMPREG1, 0)); 
    }
}

//0F 94 Ia_setz_Eb
void IA32Interpreter::rorm_setz(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));

	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);

	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

// OF 92 Ia_setb_Eb
void IA32Interpreter::rorm_setb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
   	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	
   	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

// 0f 96 Ia_setbe_Eb
void IA32Interpreter::rorm_setbe(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));

	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));

	bb->add(ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

// added by chuchao, 3.25
// 0F 93 Ia_setnb_Eb
void IA32Interpreter::rorm_setnb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	    bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    	// bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	    // bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (LI(1, TEMPREG2));
     bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
					if (insn->rm < 4)
					{
									bb->add (IA32GET(insn->rm, VREG(insn->rm)));
									bb->add (LI(0xffffff00, TEMPREG1));
									bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
									bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
									bb->add (IA32PUT(VREG(insn->rm), insn->rm));
					}
					else
					{
									insn->rm -= 4;
									bb->add (IA32GET(insn->rm, VREG(insn->rm)));
									bb->add (LI(0xffff00ff, TEMPREG1));
									bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
									bb->add (LI(0x8, TEMPREG3));
									bb->add (SLL(TEMPREG2, TEMPREG3, TEMPREG2));
									bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
									bb->add (IA32PUT(VREG(insn->rm), insn->rm));
					}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);

	    bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    	// bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	    // bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(1, TEMPREG2));
     bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
}


// 0F 97 Ia_setnbe_Eb
void IA32Interpreter::rorm_setnbe(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	    bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	    bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (LI(1, TEMPREG1));
     bb->add (SUB(TEMPREG1, TEMPREG2, TEMPREG1));
					if (insn->rm < 4)
					{
									bb->add (IA32GET(insn->rm, VREG(insn->rm)));
									bb->add (LI(0xffffff00, TEMPREG2));
									bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
									bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
									bb->add (IA32PUT(VREG(insn->rm), insn->rm));
					}
					else
					{
									insn->rm -= 4;
									bb->add (IA32GET(insn->rm, VREG(insn->rm)));
									bb->add (LI(0xffff00ff, TEMPREG2));
									bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
									bb->add (LI(0x8, TEMPREG3));
									bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
									bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
									bb->add (IA32PUT(VREG(insn->rm), insn->rm));
					}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);

	    bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	    bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(1, TEMPREG2));
     bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
}

// 0F 9C Ia_setl_Eb 
void IA32Interpreter::rorm_setl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
  	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
     	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));
	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
    	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
  	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
     	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));

	bb->add(ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

// 0F 9E Ia_setle_Eb
void IA32Interpreter::rorm_setle(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
  	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
     	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));
	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
  	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
     	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG2));
	bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));

	bb->add(ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

// 0F 9D Ia_setnl_Eb
void IA32Interpreter::rorm_setnl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
       	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
    	bb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG1));
	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
       	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
    	bb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG3));

	bb->add (ST(TEMPREG3, BYTE, t, mm_->map(0)));
    }
}

// checkpoint

// 0F 9F Ia_setnel_Eb 
void IA32Interpreter::rorm_setnle(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
	bb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG3));
    	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
    	bb->add (LI(1, TEMPREG2));
    	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
    	bb->add (AND(TEMPREG2, TEMPREG3, TEMPREG1));
	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
    	bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    	bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG2));
	bb->add (CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG3));
    	bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
    	bb->add (LI(1, TEMPREG2));
    	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
    	bb->add (AND(TEMPREG2, TEMPREG3, TEMPREG2));

	bb->add(ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
}

//3D /id Ia_cmpw_AX_Iw
void IA32Interpreter::AX_i_cmpw3d(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // op_size = HALFWORD;
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
}

//39 /r Ia_cmpw_Ew_Gw
void IA32Interpreter::rorm_r_cmpw39(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	//op_size = HALFWORD;
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));

	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), VREG(op->op2.reg)));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
    	//op_size = HALFWORD;
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG1, VREG(op->op2.reg)));
    }
}

// 81 /7 iw Ia_cmpw_Ew_Iw
void IA32Interpreter::rorm_i_cmpw81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	//op_size = HALFWORD;
	bb->add (LI(op->op2.imm, TEMPREG1));

	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), TEMPREG1));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));

	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG2, TEMPREG1));
    }
}

// 83 /7 ib Ia_cmpw_Ew_sIb
void IA32Interpreter::rorm_i_cmpw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	//op_size = HALFWORD;
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), TEMPREG1));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG2, TEMPREG1));
    }
}

//3B /r Ia_cmpw_Gw_Ew
void IA32Interpreter::r_rorm_cmpw3b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	//op_size = HALFWORD;
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), VREG(insn->rm)));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
    	//op_size = HALFWORD;
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), TEMPREG1));
    }
}

//39 /r Ia_cmpl_Ed_Gd 
void IA32Interpreter::rorm_r_cmpl39(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), VREG(op->op2.reg)));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG1, VREG(op->op2.reg)));
    }
}

//3B /r Ia_cmpl_Gd_Ed 
void IA32Interpreter::r_rorm_cmpl3b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), VREG(insn->rm)));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));
    }
}

//81 /7 id Ia_cmpl_Ed_Id
void IA32Interpreter::rorm_i_cmpl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
    }
}

//83 /7 Ia_cmpl_Ed_sIb
void IA32Interpreter::rorm_i_cmpl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
    }
}

//38 /7 Ia_cmpb_Eb_Gb
void IA32Interpreter::rorm_r_cmpb38(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), VREG(op->op2.reg)));
	    }
	    else
	    {
		insn->rm -= 4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, VREG(op->op2.reg)));
	    }
	}
	else
	{
	    op->op2.reg -= 4;

	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG2));
	    }
	    else
	    {
		insn->rm -= 4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG3));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG3, TEMPREG2));
	    }
	}
    }
    else
    {
	if (op->op2.reg < 4)
	{

    	    XTRegNum t = resolveModRM(insn,op,bb);

	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, VREG(op->op2.reg)));
	}
	else
	{
	    op->op2.reg -= 4;

	    XTRegNum t = resolveModRM(insn,op,bb);
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));
	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, TEMPREG2));
	}
    }
}

// 3A /r Ia_cmpb_Gb_Eb
void IA32Interpreter::r_rorm_cmpb3a(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op1.reg < 4)
	{
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(op->op1.reg), VREG(insn->rm)));
	    }
	    else
	    {
		insn->rm -= 4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(op->op1.reg), TEMPREG2));
	    }
	}
	else
	{
	    op->op1.reg -= 4;
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG2));

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, VREG(insn->rm)));
	    }
	    else
	    {
		insn->rm -= 4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG3));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG3));
	    }
	}
    }
    else
    {
	if (op->op1.reg < 4)
	{
    	    XTRegNum t = resolveModRM(insn,op,bb);
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(op->op1.reg), TEMPREG1));
	}
	else
	{
    	    XTRegNum t = resolveModRM(insn,op,bb);

	    op->op1.reg -= 4;
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG2));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));
	}
    }
}

//80 /7 Ia_cmpb_Eb_Ib
void IA32Interpreter::rorm_i_cmpb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (LI(op->op2.imm, TEMPREG1));

	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG1));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG3, TEMPREG1));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
    	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));
    }
}

//0F 85 Ia_jne_Jd		(ZF == 0)
void IA32Interpreter::i_jned(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
    bb->add (BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

// 7C Ia_jl_Jb
void IA32Interpreter::i_jlb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add (BRANCH(NE, TEMPREG1, TEMPREG2, 0, op->op1.imm));	
}

// 0F 8C Ia_jl_Jd
void IA32Interpreter::i_jld(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add (BRANCH(NE, TEMPREG1, TEMPREG2, 0, op->op1.imm));	
}

//0F 8E Ia_jle_Jd		(ZF == 1 or SF != OF)
void IA32Interpreter::i_jled(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG3));
    bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));
    bb->add (OR(TEMPREG1, TEMPREG3, TEMPREG1));
    bb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));	
}

//7E Ia_jle_Jb
void IA32Interpreter::i_jleb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    i_jled(insn, op, bb);
}

//85 /r Ia_testl_Ed_Gd
void IA32Interpreter::rorm_r_testl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

	if ((op->op2.reg) == (insn->rm))
	{
	    bb->add (CALL((Word)(&crossbit::set_flags_testl), 1, VREG(op->op2.reg)));
	}
	else
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
	    bb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));
    }
}

//85 /r Ia_testw_Ew_Gw
void IA32Interpreter::rorm_r_testw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

	if ((op->op2.reg) == (insn->rm))
	{
	    bb->add (CALL((Word)(&crossbit::set_flags_testw), 1, VREG(op->op2.reg)));
	}
	else
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
	    bb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
    }
}

//F7 /0 iw Ia_testw_Ew_Iw
void IA32Interpreter::rorm_i_testw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testw), 1, TEMPREG1));
    }
}

//A8 ib Ia_testb_AL_Ib
void IA32Interpreter::AL_i_testb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
}

// A9 id Ia_testl_EAX_Id
void IA32Interpreter::EAX_i_testl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));	
}

//F6 /0 ib Ia_testb_Eb_Ib
void IA32Interpreter::rorm_i_testb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (LI (op->op2.imm, TEMPREG1));

	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));	
	}
	else
	{
	    insn->rm -= 4;
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    	    bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LI (op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));	
    }
}

//F7 /0 Ia_testl_Ed_Id
void IA32Interpreter::rorm_i_testl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));	
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_testl), 1, TEMPREG1));	
    }
}

//74 Ia_jz_Jb				(ZF == 1)
void IA32Interpreter::i_jzb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
    bb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//EB Ia_jmp_Jb
void IA32Interpreter::i_jmpb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("i_jmpb\n");
    //bb->add(JMP(0, op->op1.imm));
    insn->ilen = op->op1.imm - curNext;
}

//72 Ia_jb_Jb  Note: jb is the same meaning of jc.The last letter b is the imm size of the insn
void IA32Interpreter::i_jbb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    bb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

// 0F 82 Ia_jb_Jd  
// Note: jb is the same meaning of jc.The last letter b is the imm size of the insn
void IA32Interpreter::i_jbd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    bb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

// 78 cb Ia_js_Jb  
void IA32Interpreter::i_jsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    bb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//OF 88 cb Ia_js_Jd  
void IA32Interpreter::i_jsd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    bb->add (BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//79 cb Ia_jns_Jb  
void IA32Interpreter::i_jnsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    bb->add (BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

// 0F 89 Ia_jns_Jd  
void IA32Interpreter::i_jnsd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::SF, TEMPREG1));
    bb->add (BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

// 30 /r Ia_xorb_Eb_Gb
void IA32Interpreter::rorm_r_xorb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (XOR(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
		bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -=4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (XOR(TEMPREG2, VREG(op->op2.reg), TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG2));

		bb->add (LI(0xffff00ff, TEMPREG1));
		bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
		bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
	else
	{
	    op->op2.reg -=4;
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (XOR(VREG(insn->rm), TEMPREG3, TEMPREG1));
		bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));

		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -=4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (XOR(TEMPREG2, TEMPREG3, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG2));

		bb->add (LI(0xffff00ff, TEMPREG1));
		bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
		bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	    bb->add (XOR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	    bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
	else
	{
	    op->op2.reg -=4;
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));

	    bb->add (XOR(TEMPREG1, TEMPREG3, TEMPREG1));
	    bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
    }
}

// 80 /6 ib Ia_xorb_Eb_ib
void IA32Interpreter::rorm_i_xorb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));

	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (XOR(VREG(insn->rm), TEMPREG1, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG2));
	    bb->add (LI(0xff, TEMPREG1));
	    bb->add (AND(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
	    bb->add (XOR(TEMPREG3, TEMPREG1, TEMPREG3));
    	    bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG3));

	    bb->add (LI(0xffff00ff, TEMPREG1));
    	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (ZEXT(TEMPREG3, BYTE, TEMPREG2));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_xorb), 1, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

//31 Ia_xorl_Ed_Gd
void IA32Interpreter::rorm_r_xorl31(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (XOR(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (XOR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//81 Ia_xorl_Ed_Id
void IA32Interpreter::rorm_r_xorl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (XOR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//33 Ia_xorl_Gd_Ed
void IA32Interpreter::r_rorm_xorl33(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (XOR(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (XOR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//83 Ia_xorl_Ed_sIb
void IA32Interpreter::rorm_i_xorl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (XOR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (XOR(TEMPREG1, TEMPREG2, TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_xorl), 1, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//31 Ia_xorw_Ew_Gw
void IA32Interpreter::rorm_r_xorw31(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (XOR(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_xorw), 1, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (XOR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_xorw), 1, TEMPREG1));
	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));
    }
}

//40+rd Ia_incl_ERX
void IA32Interpreter::r_incl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

    bb->add (CALL((Word)(&crossbit::set_flags_incl1), 1, VREG(op->op1.reg)));
    bb->add (ADDI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

// FE /0 Ia_incb_Eb
void IA32Interpreter::rorm_incb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_incb1), 1, VREG(insn->rm)));

    	    bb->add (ADDI(VREG(insn->rm), 1, TEMPREG1));
	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -=4;
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_incb1), 1, TEMPREG2));

    	    bb->add (ADDI(TEMPREG2, 1, TEMPREG2));
	    bb->add (LI(0xffff00ff, TEMPREG1));
    	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_incb1), 1, TEMPREG1));

	bb->add (ADDI(TEMPREG1, 1, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));	
    }
}

//FF /0  Ia_incl_Ed
void IA32Interpreter::rorm_incl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_incl1), 1, VREG(insn->rm)));

	bb->add (ADDI(VREG(insn->rm), 1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_incl1), 1, TEMPREG1));

	bb->add (ADDI(TEMPREG1, 1, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));	
    }
}

// FF /0  Ia_incl_Ew
void IA32Interpreter::rorm_incw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{

    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_incw1), 1, VREG(insn->rm)));

	bb->add (ADDI(VREG(insn->rm), 1, TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_incw1), 1, TEMPREG1));

	bb->add (ADDI(TEMPREG1, 1, TEMPREG1));
	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));
    }
}

// 40 + rw Ia_incw_RX
void IA32Interpreter::r_incw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    bb->add (CALL((Word)(&crossbit::set_flags_incw1), 1, VREG(op->op1.reg)));

    bb->add (ADDI(VREG(op->op1.reg), 1, TEMPREG1));
    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

// FF /1 Ia_decw_Ew
void IA32Interpreter::rorm_decw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_decw1), 1, VREG(insn->rm)));

	bb->add (SUBI(VREG(insn->rm), 1, TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_decw1), 1, TEMPREG1));

	bb->add (SUBI(TEMPREG1, 1, TEMPREG1));
	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));	
    }
}

// 48 + rw Ia_decw_RX
void IA32Interpreter::decw_rx(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    bb->add (CALL((Word)(&crossbit::set_flags_decw1), 1, VREG(op->op1.reg)));

    bb->add (SUBI(VREG(op->op1.reg), 1, TEMPREG1));
    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

//FE Ia_decb_Eb
void IA32Interpreter::rorm_decb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    //op_size = BYTE;
    if (insn->mod == 3)
    {

	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_decb1), 1, VREG(insn->rm)));

    	    bb->add (SUBI(VREG(insn->rm), 1, TEMPREG1));
	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -=4;
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_decb1), 1, TEMPREG2));

    	    bb->add (SUBI(TEMPREG2, 1, TEMPREG2));
	    bb->add (LI(0xffff00ff, TEMPREG1));
    	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_decb1), 1, TEMPREG1));

	bb->add (SUBI(TEMPREG1, 1, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

// A0 Ia_movb_AL_Ob
void IA32Interpreter::Ob_movb_AL(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (LD(TEMPREG1, mm_->map(0), BYTE, TEMPREG1));
    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(0xffffff00, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//A2 Ia_movb_Ob_AL
void IA32Interpreter::AL_movb_Ob(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(op->op1.imm, TEMPREG1));
    bb->add (ST(VREG(IA32ProcessorState::EAX), BYTE, TEMPREG1, mm_->map(0)));
}

//8A /r  Ia_movb_Gb_Eb
void IA32Interpreter::r_rorm_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op1.reg < 4)
	{
	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0xff, TEMPREG1));
		bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -= 4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (ZEXT(VREG(insn->rm), HALFWORD, TEMPREG1));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(TEMPREG1, TEMPREG2, TEMPREG1));

		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
	else
	{
	    op->op1.reg -= 4;

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0xff, TEMPREG1));
		bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -= 4;
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0xff00, TEMPREG1));
		bb->add (AND(VREG(insn->rm), TEMPREG1, TEMPREG2));

		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0xffff00ff, TEMPREG1));
		bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));

	if (op->op1.reg < 4)
	{
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    op->op1.reg -= 4;
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG2));
	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
}

//C6 /0 Ia_movb_Eb_Ib
void IA32Interpreter::rorm_i_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = BYTE;

    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
	    bb->add (LI(op->op2.imm, TEMPREG1));
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (LI((op->op2.imm << 8), TEMPREG1));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
}

//88 /r Ia_movb_Eb_Gb
void IA32Interpreter::rorm_r_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = BYTE;
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
            bb->add (ZEXT(VREG(op->op2.reg), BYTE, TEMPREG1));

	    if (op->op1.reg < 4)
	    {
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	        bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		op->op1.reg -=4;
		bb->add (LI(0x8, TEMPREG3));
		bb->add (SLL(TEMPREG1, TEMPREG3, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	        bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
	else
	{
	    op->op2.reg -=4;
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    if (op->op1.reg < 4)
	    {
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	        bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		op->op1.reg -=4;
		bb->add (LI(0xff00, TEMPREG3));
		bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	        bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (ST(VREG(op->op2.reg), BYTE, t, mm_->map(0)));
	}
	else
	{
	    op->op2.reg -=4;
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LI(0x8, TEMPREG2));
    	    bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
    }
}

//B0-B7 Ia_movb_R8_Ib
void IA32Interpreter::r_i_movb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (op->op1.reg < 4)
    {
        bb->add (LI ((Word)op->op2.imm, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LI(0xffffff00, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
	op->op1.reg -= 4;
	bb->add (LI((Word)(op->op2.imm << 8), TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LI(0xffff00ff, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// A5 Ia_movsl_Yd_Xd
void IA32Interpreter::movsl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{

    bb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    bb->add (USE(IA32ProcessorState::ESI));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
	bb->add (LABEL(0));
    }

    bb->add (LD(VREG(IA32ProcessorState::ESI), mm_->map(0), WORD, TEMPREG1));
    bb->add (ADDI(VREG(IA32ProcessorState::ESI), 4, VREG(IA32ProcessorState::ESI)));
    bb->add (ST(TEMPREG1, WORD, VREG(IA32ProcessorState::EDI), mm_->map(0)));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 4, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
       	bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	bb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

	hasRep = false;
	bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// A5 Ia_movsw_Yw_Xw
void IA32Interpreter::movsw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    bb->add (USE(IA32ProcessorState::ESI));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	    bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
	    bb->add (LABEL(0));
    }

    bb->add (LD(VREG(IA32ProcessorState::ESI), mm_->map(0), HALFWORD, TEMPREG1));
    bb->add (ADDI(VREG(IA32ProcessorState::ESI), 2, VREG(IA32ProcessorState::ESI)));
    bb->add (ST(TEMPREG1, HALFWORD, VREG(IA32ProcessorState::EDI), mm_->map(0)));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 2, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
     bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	    bb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

	    hasRep = false;
	    bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// AA Ia_stosb_Yb_AL
void IA32Interpreter::stosb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (USE(IA32ProcessorState::EAX));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
   	bb->add (LABEL(0)); 
    }

    // There may be a bug here. The EAX will be assigned as BL.
    bb->add (ST(VREG(IA32ProcessorState::EAX), BYTE, VREG(IA32ProcessorState::EDI), mm_->map(0)));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
       	bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	bb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));
	hasRep = false;
	bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// AB Ia_stosw_Yw_AX
void IA32Interpreter::stosw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
   
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (USE(IA32ProcessorState::EAX));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
   	bb->add (LABEL(0)); 
    }

    bb->add (ST(VREG(IA32ProcessorState::EAX), HALFWORD, VREG(IA32ProcessorState::EDI), mm_->map(0)));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 2, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
       	bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	bb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));


	hasRep = false;
	bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// AB Ia_stosd_Yd_EAX
void IA32Interpreter::stosd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (USE(IA32ProcessorState::EAX));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
   	bb->add (LABEL(0)); 
    }

    bb->add (ST(VREG(IA32ProcessorState::EAX), WORD, VREG(IA32ProcessorState::EDI), mm_->map(0)));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 4, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
       	bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	bb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

	hasRep = false;
	bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

//CD Ia_int_Ib
void IA32Interpreter::i_int(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    bb->add (SYSCALL);
}

//CC Ia_int_Ib
void IA32Interpreter::int3(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    bb->add (HALT(op->op1.imm-1));
}

//68 Ia_pushl_Id
//6A Ia_pushl_sIb
void IA32Interpreter::i_pushl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // The PUSH ESP instruction pushes the value of the ESP register 
    // as it existed before the instruction was executed
    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));		// t1 = R[%esp]
    //bb->add (LI(4, TEMPREG1));						// t2 = 4
    //bb->add (SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));// t1 = t1 - t2
    bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));// t1 = t1 - t2
    bb->add (LI(op->op1.imm, TEMPREG1));				// t3 = rA
    bb->add (ST(TEMPREG1, WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));	// M[t1] = t3
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));		// R[%esp] = t1
}

//E8 Ia_call_Jd
void IA32Interpreter::i_call(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("i_call\n");
    bb->add (LI((MemAddr)op->op2.imm, TEMPREG2));			// t1 = next
    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));		// t2 = R[%esp]
    //bb->add (LI(4, TEMPREG1));						// t3 = 4
    //bb->add (SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));// t2 = t2 - t3
    bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));// t2 = t2 - t3
    bb->add (ST(TEMPREG2, WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));	// M[t2] = t1
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));		// R[%esp] = t2
    //bb->add (JMP(0, op->op1.imm));					// JMP (dest)0
    insn->ilen = op->op1.imm - curNext;
}

// 99 Ia_cdq
void IA32Interpreter::cdq(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (CMP(LT, VREG(IA32ProcessorState::EAX), 0, TEMPREG1));
    bb->add (SUB(0, TEMPREG1, VREG(IA32ProcessorState::EDX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
}

// 98 Ia_cwde
void IA32Interpreter::cwtl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (SEXT(VREG(IA32ProcessorState::EAX), HALFWORD, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//FF /2 Ia_call_Ed
void IA32Interpreter::rorm_call(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (LI((MemAddr)op->op2.imm, TEMPREG1));
    	bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    	bb->add (ST(TEMPREG1, WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));
    	bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (JMP(VREG(insn->rm), 0));
    }
    else
    {
	bb->add (LI((MemAddr)op->op2.imm, TEMPREG1));
    	bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    	bb->add (ST(TEMPREG1, WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));
    	bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (JMP(TEMPREG1, 0));
    }
}

// checkpoint

//8B Ia_movl_Gd_Ed
void IA32Interpreter::r_rorm_movl8b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (MOV(VREG(insn->rm), VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

void IA32Interpreter::r_rorm_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (ZEXT(VREG(insn->rm), HALFWORD, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// D3 /0 Ia_roll_Ed_CL
void IA32Interpreter::cl_roll(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));

	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LI(0x1f, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_roll), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SLL(VREG(insn->rm), TEMPREG1, TEMPREG2));
	bb->add (LI(32, TEMPREG3));
	bb->add (SUB(TEMPREG3, TEMPREG1, TEMPREG3));
	bb->add (SRL(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);

	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));

	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LI(0x1f, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));

	bb->add (CALL((Word)(&crossbit::set_flags_roll), 2, TEMPREG2, TEMPREG1));

	bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG3));
	bb->add (LI(32, TEMPREG4));
	bb->add (SUB(TEMPREG4, TEMPREG1, TEMPREG4));
	bb->add (SRL(TEMPREG2, TEMPREG4, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG3, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}
// 9C
void IA32Interpreter::pushf_eflags(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{

	bb->add(LI(TTT, TEMPREG2));
	bb->add(CALL((XTInt32)(&crossbit::createEFLAGS), 1, TEMPREG2));
	bb->add(IA32GET(TTT, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    bb->add (SUBI(VREG(IA32ProcessorState::ESP), 2, VREG(IA32ProcessorState::ESP)));// t1 = t1 - t2
//    bb->add (LI(op->op1.imm, TEMPREG1));				// t3 = rA
    bb->add (ST(TEMPREG1, HALFWORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));	// M[t1] = t3
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));		// R[%esp] = t1

}
// 9D
void IA32Interpreter::popf_eflags(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    bb->add (LD(VREG(IA32ProcessorState::ESP), mm_->map(0), HALFWORD, TEMPREG1));
	bb->add(CALL((XTInt32)(&crossbit::set_flags_popf), 1, TEMPREG1));
    bb->add (ADDI(VREG(IA32ProcessorState::ESP), 2, VREG(IA32ProcessorState::ESP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

}
// D1 /0 Ia_roll_Eb_I1
void IA32Interpreter::rorm_roll(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (LI(1, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_roll), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SLL(VREG(insn->rm), TEMPREG1, TEMPREG2));
	bb->add (LI(31, TEMPREG3));
	bb->add (SRL(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);

	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (LI(0x1, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_roll), 2, TEMPREG2, TEMPREG1));

	bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG3));
	bb->add (LI(31, TEMPREG4));
	bb->add (SRL(TEMPREG2, TEMPREG4, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG3, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

// C1 /1 ib Ia_rorl_Ed_Ib
void IA32Interpreter::rorm_i_rorl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (LI((op->op2.imm & 0x1f), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_rorl), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
	bb->add (LI(32, TEMPREG3));
	bb->add (SUB(TEMPREG3, TEMPREG1, TEMPREG3));
	bb->add (SLL(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (LI((op->op2.imm & 0x1f), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_rorl), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG3));
	bb->add (LI(32, TEMPREG4));
	bb->add (SUB(TEMPREG4, TEMPREG1, TEMPREG4));
	bb->add (SLL(TEMPREG2, TEMPREG4, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG3, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

// C1 /1 Ia_rorw_Ew_Ib
void IA32Interpreter::rorm_i_rorw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (LI((op->op2.imm & 0xf), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_rorw), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
	bb->add (LI(16, TEMPREG3));
	bb->add (SUB(TEMPREG3, TEMPREG1, TEMPREG3));
	bb->add (SLL(VREG(insn->rm), TEMPREG3, TEMPREG1));
	bb->add (OR(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (LI((op->op2.imm & 0xf), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_rorw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG3));
	bb->add (LI(16, TEMPREG4));
	bb->add (SUB(TEMPREG4, TEMPREG1, TEMPREG4));
	bb->add (SLL(TEMPREG2, TEMPREG4, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG3, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//C2 Ia_ret_Ew
void IA32Interpreter::i_ret(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    bb->add (LD(VREG(IA32ProcessorState::ESP), mm_->map(0), WORD, TEMPREG1));
    //bb->add (LI((op->op1.imm + 4), TEMPREG2));
    //bb->add (ADD(VREG(IA32ProcessorState::ESP), TEMPREG2, VREG(IA32ProcessorState::ESP)));
    bb->add (ADDI(VREG(IA32ProcessorState::ESP), (op->op1.imm + 4), VREG(IA32ProcessorState::ESP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

    bb->add (JMP(TEMPREG1, 0));
}

//C3 Ia_ret
void IA32Interpreter::ret(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    bb->add (LD(VREG(IA32ProcessorState::ESP), mm_->map(0), WORD, TEMPREG1));
    //bb->add (LI(4, TEMPREG2));
    //bb->add (ADD(VREG(IA32ProcessorState::ESP), TEMPREG2, VREG(IA32ProcessorState::ESP)));
    bb->add (ADDI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    bb->add (JMP(TEMPREG1, 0));
}

//added by zhengjuyu
//modified by Chuchao
//80 /2 Ia_adcb_Eb_Ib
//TODO
void IA32Interpreter::rorm_i_adcb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    XTRegNum t = resolveModRM(insn, op, bb);
    bb->add (LI(op->op2.imm, t2));
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, t3));

    }
    else
    {
	printf("adcb_ib\n");
	exit(0);
    }
    printf("adcb_ib\n");
    exit(0);
}

//added by zhengjuyu
//
void IA32Interpreter::adcl_id(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    XTRegNum t = resolveModRM(insn, op, bb);
    bb->add (LI(op->op2.imm, t2));
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, t3));

    }
    else
    {
	printf("adcl_id\n");
	exit(0);
    }
    printf("adcl_id\n");
    exit(0);
}

// A bug here, the flags may be wrong!
// 83 /2 ib Ia_adcl_Ed_sIb
void IA32Interpreter::adcl_sib(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, VREG(insn->rm), TEMPREG1, TEMPREG2));

	bb->add (ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));

	bb->add (ADD(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
    	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG3));
	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, TEMPREG3, TEMPREG1, TEMPREG2));

	bb->add (ADD(TEMPREG3, TEMPREG1, TEMPREG3));
	bb->add (ADD(TEMPREG3, TEMPREG2, TEMPREG3));
	bb->add (ST(TEMPREG3, WORD, t, mm_->map(0)));
    }
}

// 0F C1 Ia_xaddl_Ed_Gd
void IA32Interpreter::rorm_r_xaddl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op2.reg), VREG(insn->rm)));

	bb->add (ADD(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
	bb->add (MOV(VREG(insn->rm), VREG(op->op2.reg)));
	bb->add (MOV(TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	bb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op2.reg), TEMPREG1));

	bb->add (ADD(VREG(op->op2.reg), TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
	bb->add (MOV(TEMPREG1, VREG(op->op2.reg)));
	bb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
    }
}

//01 /r Ia_addl_Ed_Gd
void IA32Interpreter::rorm_r_addl01(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op2.reg), VREG(insn->rm)));

	bb->add (ADD(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, TEMPREG1, VREG(op->op2.reg)));

	bb->add (ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//11 /r Ia_adcl_Ed_Gd
void IA32Interpreter::rorm_r_adcl11(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));

    	bb->add (ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (ADD(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_adcl), 3, TEMPREG2, VREG(op->op2.reg), TEMPREG1));

	bb->add (ADD(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ADD(TEMPREG2, VREG(op->op2.reg), TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

//03 /r Ia_addl_Gd_Ed
void IA32Interpreter::r_rorm_addl03(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op1.reg), VREG(insn->rm)));

	bb->add (ADD(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(op->op1.reg), TEMPREG1));

	bb->add (ADD(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 04 ib Ia_addb_AL_Ib
void IA32Interpreter::AL_i_addb04(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{

    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));

    bb->add (ADD(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (LI(0xffffff00, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(0xff, TEMPREG2));
    bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

// 2C ib Ia_subb_AL_Ib
void IA32Interpreter::AL_i_subb2c(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{

    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));

    bb->add (SUB(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (LI(0xffffff00, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(0xff, TEMPREG2));
    bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}


// 00 /r Ia_addb_Eb_Gb
void IA32Interpreter::rorm_r_addb00(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(insn->rm), VREG(op->op2.reg)));

		bb->add (ADD(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -= 4;

		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, VREG(op->op2.reg)));

		bb->add (ADD(TEMPREG2, VREG(op->op2.reg), TEMPREG1));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xff00, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
	else
	{
	    op->op2.reg -= 4;

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(insn->rm), TEMPREG3));

		bb->add (ADD(VREG(insn->rm), TEMPREG3, TEMPREG1));
		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -= 4;

		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, TEMPREG3));

		bb->add (ADD(TEMPREG2, TEMPREG3, TEMPREG1));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xff00, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t,mm_->map(0),BYTE,TEMPREG1));

	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG1, VREG(op->op2.reg)));

    	    bb->add (ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
	else
	{
	    op->op2.reg -= 4;
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LI(0x8, TEMPREG2));
    	    bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
    	    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG1, TEMPREG3));

    	    bb->add (ADD(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
    }
}

// 80 Ia_addb_Eb_Ib
void IA32Interpreter::rorm_i_addb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(insn->rm), TEMPREG1));

    	    bb->add (ADD(VREG(insn->rm), TEMPREG1, TEMPREG2));
	    bb->add (LI(0xff, TEMPREG1));
	    bb->add (AND(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    	    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG3, TEMPREG1));

    	    bb->add (ADD(TEMPREG3, TEMPREG1, TEMPREG3));
	    bb->add (SLL(TEMPREG3, TEMPREG2, TEMPREG3));
	    bb->add (LI(0xff00, TEMPREG1));
	    bb->add (AND(TEMPREG3, TEMPREG1, TEMPREG3));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, TEMPREG1));

	bb->add (ADD(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
}

//02 Ia_addb_Gb_Eb
void IA32Interpreter::r_rorm_addb02(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op1.reg < 4)
	{
	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(op->op1.reg), VREG(insn->rm)));

		bb->add (ADD(VREG(op->op1.reg), VREG(insn->rm), TEMPREG1));
		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -= 4;

		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(op->op1.reg), TEMPREG2));

		bb->add (ADD(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
	else
	{
	    op->op1.reg -= 4;

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG3));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG3, VREG(insn->rm)));

		bb->add (ADD(TEMPREG3, VREG(insn->rm), TEMPREG3));
		bb->add (ZEXT(TEMPREG3, BYTE, TEMPREG3));
		bb->add (SLL(TEMPREG3, TEMPREG1, TEMPREG3));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG3, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -= 4;

		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(op->op1.reg), TEMPREG1, TEMPREG3));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG3, TEMPREG2));

		bb->add (ADD(TEMPREG3, TEMPREG2, TEMPREG3));
		bb->add (ZEXT(TEMPREG3, BYTE, TEMPREG3));
		bb->add (SLL(TEMPREG3, TEMPREG1, TEMPREG3));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG3, VREG(op->op1.reg)));
		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));

	if (op->op1.reg < 4)
	{
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, VREG(op->op1.reg), TEMPREG1));

    	    bb->add (ADD(VREG(op->op1.reg), TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    op->op1.reg -=4;

    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SRL(VREG(op->op1.reg), TEMPREG3, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_addb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (ADD(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (SLL(TEMPREG2, TEMPREG3, TEMPREG2));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
}

//03 /r Ia_addw_Ew_Gw
void IA32Interpreter::rorm_r_addw01(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(op->op2.reg), VREG(insn->rm)));

	bb->add (ADD(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_addw), 2, TEMPREG1, VREG(op->op2.reg)));
	bb->add (ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));
    }
}

//03 /r Ia_addw_Gw_Ew
void IA32Interpreter::r_rorm_addw03(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(op->op1.reg), VREG(insn->rm)));
	
	bb->add (ADD(VREG(op->op1.reg), VREG(insn->rm), TEMPREG2));
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(op->op1.reg), TEMPREG1));

	bb->add (ADD(TEMPREG1, VREG(op->op1.reg), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//05 Ia_addl_EAX_Id
void IA32Interpreter::EAX_i_addl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));

    bb->add (ADD(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//81 /0 Ia_addl_Ed_Id
void IA32Interpreter::rorm_i_addl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    rorm_i_addl83(insn, op, bb);
}

//83 /0 Ia_addl_Ed_sIb
void IA32Interpreter::rorm_i_addl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2,VREG(insn->rm), TEMPREG1));

	bb->add (ADD(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_addl), 2, TEMPREG2, TEMPREG1));

	bb->add (ADD(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

//83 /0 Ia_addl_Ed_sIb
void IA32Interpreter::rorm_i_addw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_addw), 2, VREG(insn->rm), TEMPREG1));

	bb->add (ADD(TEMPREG1, VREG(insn->rm), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_addw), 2, TEMPREG2, TEMPREG1));

	bb->add (ADD(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//58-5F Ia_popl_ERX
void IA32Interpreter::r_popl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    bb->add (LD(VREG(IA32ProcessorState::ESP), mm_->map(0), WORD, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg ));
    //bb->add (LI(4, TEMPREG1));
    //bb->add (ADD(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    bb->add (ADDI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
}

//21 /r Ia_andw_Ew_Gw
void IA32Interpreter::rorm_r_andw21(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));
    }
}

//21 /r Ia_andl_Ed_Gd
void IA32Interpreter::rorm_r_andl21(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));

	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG1));

	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//22 /r Ia_andw_Gd_Ed
void IA32Interpreter::r_rorm_andb22(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = BYTE;

    if (insn->mod == 3)
    {
	if (op->op1.reg < 4)
	{
	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (AND(VREG(op->op1.reg), VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -=4;
    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (AND(VREG(op->op1.reg), TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
	else
	{
	    op->op1.reg -= 4;

	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -=4;

    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));

	if (op->op1.reg < 4)
	{
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    	    bb->add (AND(TEMPREG1, VREG(op->op1.reg), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    op->op1.reg -= 4;

    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG3));
    	    bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
}

//23 /r Ia_andl_Gd_Ed
void IA32Interpreter::r_rorm_andl23(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));

	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));

	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 20 Ia_andb_Eb_Gb
void IA32Interpreter::rorm_r_andb20(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -= 4;
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (AND(VREG(op->op2.reg), TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
	else
	{
	    op->op2.reg -= 4;

	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -=4;

    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);

	if (op->op2.reg < 4)
	{
    	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
	else
	{
	    op->op2.reg -= 4;

 	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
    }
    /*
    op_size = BYTE;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(insn->rm)));

	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
    */
}

// 24 ib Ia_andb_AL_Ib
void IA32Interpreter::AL_i_andb24(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = BYTE;

    bb->add (LI((Word)op->op2.imm, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
    bb->add (LI(0xffffff00, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//80 /4 Ia_andb_Eb_Ib
void IA32Interpreter::rorm_i_andb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = BYTE;

    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (LI((Word)op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (LI((Word)op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    	    bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (AND(TEMPREG2, TEMPREG1, TEMPREG2));
    	bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG2));

	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
}

//81 /4 Ia_andw_Ew_Iw
void IA32Interpreter::rorm_i_andw81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (AND(TEMPREG2, TEMPREG1, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG2));

	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//81 /4 Ia_andl_Ed_Id
void IA32Interpreter::rorm_i_andl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    rorm_i_andl83(insn, op, bb);
}

//83 /4 Ia_andl_Ed_sIb
void IA32Interpreter::rorm_i_andl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));

	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (AND(TEMPREG2, TEMPREG1, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG2));

	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

//28 /r Ia_subb_Eb_Gb
void IA32Interpreter::rorm_r_subb28(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), VREG(op->op2.reg)));

		bb->add (SUB(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -= 4;

		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, VREG(op->op2.reg)));

		bb->add (SUB(TEMPREG2, VREG(op->op2.reg), TEMPREG1));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xff00, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
	else
	{
	    op->op2.reg -= 4;

	    if (insn->rm < 4)
	    {
		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG3));

		bb->add (SUB(VREG(insn->rm), TEMPREG3, TEMPREG1));
		bb->add (LI(0xff, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -= 4;

		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG1, TEMPREG3));
		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG1));
		bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
		bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG3));

		bb->add (SUB(TEMPREG2, TEMPREG3, TEMPREG1));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xff00, TEMPREG2));
		bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t,mm_->map(0),BYTE,TEMPREG1));

	if (op->op2.reg < 4)
	{
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, VREG(op->op2.reg)));

    	    bb->add (SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
	else
	{
	    op->op2.reg -= 4;
	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LI(0x8, TEMPREG2));
    	    bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, TEMPREG3));

    	    bb->add (SUB(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
    }

    /*
    op_size = BYTE;

    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), VREG(op->op2.reg)));

	bb->add (SUB(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG1, VREG(op->op2.reg)));

	bb->add (SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }
    */
}

// 28 /r Ia_subb_Eb_Ib
void IA32Interpreter::rorm_i_subb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG1));

    	    bb->add (SUB(VREG(insn->rm), TEMPREG1, TEMPREG2));
	    bb->add (LI(0xff, TEMPREG1));
	    bb->add (AND(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    	    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG3, TEMPREG1));

    	    bb->add (SUB(TEMPREG3, TEMPREG1, TEMPREG3));
	    bb->add (SLL(TEMPREG3, TEMPREG2, TEMPREG3));
	    bb->add (LI(0xff00, TEMPREG1));
	    bb->add (AND(TEMPREG3, TEMPREG1, TEMPREG3));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG3, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));

	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }

    /*
    op_size = BYTE;
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));

	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
    */
}

//29 /r Ia_subl_Ed_Gd
void IA32Interpreter::rorm_r_subl29(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), VREG(op->op2.reg)));

	bb->add (SUB(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG1, VREG(op->op2.reg)));

	bb->add (SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//2B /r Ia_subl_Gd_Ed
void IA32Interpreter::r_rorm_subl2b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), VREG(insn->rm)));

	bb->add (SUB(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));

	bb->add (SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 29 /r Ia_subw_Ew_Gw
void IA32Interpreter::rorm_r_subw29(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), VREG(op->op2.reg)));

	bb->add (SUB(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG1, VREG(op->op2.reg)));

	bb->add (SUB(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));
    }
}

//2B /r Ia_subl_Gw_Ew
void IA32Interpreter::r_rorm_subw2b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), VREG(insn->rm)));

	bb->add (SUB(VREG(op->op1.reg), VREG(insn->rm), TEMPREG2));		
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(op->op1.reg), TEMPREG1));

	bb->add (SUB(VREG(op->op1.reg), TEMPREG1, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 81 /5 Ia_subl_Ed_Id
void IA32Interpreter::rorm_i_subl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));
	bb->add (SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));
	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

//83 /5 Ia_subl_Ed_sIb
void IA32Interpreter::rorm_i_subl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));

	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

// 83 /5 ib Ia_subw_Ew_sIb
void IA32Interpreter::rorm_i_subw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SUB(VREG(insn->rm), TEMPREG1, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subw), 2, TEMPREG2, TEMPREG1));

	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//2D Ia_subl_EAX_Id
void IA32Interpreter::EAX_i_subl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));

    bb->add (SUB(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//50-57 Ia_pushl_ERX
void IA32Interpreter::r_pushl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if ( (op->op1.reg) == IA32ProcessorState::ESP)
    {
	bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
	bb->add (MOV(VREG(IA32ProcessorState::ESP), TEMPREG1));
    	//bb->add (LI(4, TEMPREG1));
    	//bb->add (SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    	bb->add (ST(TEMPREG1, WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));
    	bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
    else
    {
        bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    	//bb->add (LI(4, TEMPREG1));
    	//bb->add (SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    	bb->add (ST(VREG(op->op1.reg), WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));
    	bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
}

//FF /6 Ia_pushl_Ed
void IA32Interpreter::rorm_pushl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    	//bb->add (LI(4, TEMPREG1));
    	//bb->add (SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (ST(VREG(insn->rm), WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));
        bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
    else
    {	
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    	//bb->add (LI(4, TEMPREG1));
    	//bb->add (SUB(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));

	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, VREG(IA32ProcessorState::ESP), mm_->map(0)));
        bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
    }
}

//B8-BF Ia_movl_ERX_Id
void IA32Interpreter::r_i_movl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LI ((Word)op->op2.imm, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

void IA32Interpreter::r_i_movw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LI ((Word)op->op2.imm, TEMPREG1));
    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

// There may be a bug here, the flags may be wrong!
//83 /3 Ia_sbbl_Ed_sIb
void IA32Interpreter::rorm_i_sbbl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
	bb->add (ADD(TEMPREG1, TEMPREG2, TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG3));
	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG2));
	bb->add (ADD(TEMPREG1, TEMPREG2, TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG3, TEMPREG1));

	bb->add (SUB(TEMPREG3, TEMPREG1, TEMPREG3));
	bb->add (ST(TEMPREG3, WORD, t, mm_->map(0)));
    }
}

//19 Ia_sbbl_Ed_Gd
void IA32Interpreter::rorm_r_sbbl19(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    	bb->add (ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SUB(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
       	bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
    	bb->add (ADD(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, TEMPREG2, TEMPREG1));

	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

// 1B /r Ia_sbbl_Gd_Ed
void IA32Interpreter::r_rorm_sbbl1b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (ADD(TEMPREG1, VREG(insn->rm), TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));

	bb->add (SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(IA32ProcessorState::CF, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (ADD(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(op->op1.reg), TEMPREG1));

	bb->add (SUB(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// A bug here, the segOver isn't processed.
//A1 Ia_movl_EAX_Od
void IA32Interpreter::EAX_mo_movl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(segOver)
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, t2));
	bb->add (IA32PUT(t2,IA32ProcessorState::EAX));	
    }
    else
    {
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(TEMPREG1, mm_->map(0), WORD, VREG(IA32ProcessorState::EAX)));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    }
}

//A3 Ia_movl_Od_EAX
void IA32Interpreter::mo_EAX_movl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if(segOver)
    {
	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (IA32GET(IA32ProcessorState::EAX, t2));
	bb->add (ST(t2, WORD, t, mm_->map(0)));
    }
    else
    {
	bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add (LI(op->op1.imm, TEMPREG1));
	bb->add (ST(VREG(IA32ProcessorState::EAX), WORD, TEMPREG1, mm_->map(0)));
    }
}

//75 Ia_jne_Jb
void IA32Interpreter::i_jneb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    i_jned(insn,op,bb);
}

//3D /id Ia_cmpl_EAX_Id
void IA32Interpreter::EAX_i_cmpl3d(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add(LI(op->op2.imm, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_subl), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
}

//3C /ib Ia_cmpb_AL_Ib
void IA32Interpreter::AL_i_cmpb3c(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{	
    //op_size = BYTE;
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
}

//0F 84 Ia_jz_Jd
void IA32Interpreter::i_jzd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    i_jzb(insn,op,bb);
}

//84 /r Ia_testl_Eb_Gb
void IA32Interpreter::rorm_r_testb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    if (insn->rm < 4)
	    {
		if (op->op2.reg == insn->rm)
		{
    		    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, VREG(op->op2.reg)));
		}
		else
		{
    		    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		    bb->add (AND(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
    		    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
		}
	    }
	    else
	    {
		insn->rm -= 4;
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (AND(VREG(op->op2.reg), TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
	    }
	}
	else
	{
	    op->op2.reg -= 4;

	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (AND(TEMPREG1, VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
	    }
	    else
	    {
		insn->rm -=4;

    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
	    }
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);

	if (op->op2.reg < 4)
	{
    	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (AND(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
	}
	else
	{
	    op->op2.reg -= 4;

 	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (AND(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_testb), 1, TEMPREG1));
	}
    }

}

//0F B6 Ia_movzbl_Gd_Eb
void IA32Interpreter::r_rorm_movzbl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (ZEXT(VREG(insn->rm), BYTE, VREG(op->op1.reg)));
	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, VREG(op->op1.reg)));
	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);

	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	bb->add (ZEXT(TEMPREG1, BYTE, VREG(op->op1.reg)));
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

}

//0F B6 Ia_movzbl_Gd_Eb
void IA32Interpreter::r_rorm_movzbw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (ZEXT(VREG(insn->rm), BYTE, TEMPREG2));

    	    //op_size = HALFWORD;
	    bb->add (LI(0xffff0000, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
    	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));

    	    //op_size = HALFWORD;
	    bb->add (LI(0xffff0000, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));

    	//op_size = HALFWORD;
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//0F B7 Ia_movzwl_Gd_Ew
void IA32Interpreter::r_rorm_movzwl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	bb->add (ZEXT(VREG(insn->rm), HALFWORD, VREG(op->op1.reg)));

    	op_size = WORD;
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
        bb->add (ZEXT(TEMPREG1, HALFWORD, VREG(op->op1.reg)));

    	op_size = WORD;
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//0F BF Ia_movswl_Gd_Ew
void IA32Interpreter::r_rorm_movswl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (SEXT(VREG(insn->rm), HALFWORD, VREG(op->op1.reg)));

    	op_size = WORD;
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (SEXT(TEMPREG1, HALFWORD, VREG(op->op1.reg)));

    	op_size = WORD;
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//0F BE Ia_movsbl_Gd_Eb
void IA32Interpreter::r_rorm_movsbl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (SEXT(VREG(insn->rm), BYTE, VREG(op->op1.reg)));

    	    op_size = WORD;
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
    	    bb->add (SEXT(TEMPREG2, BYTE, VREG(op->op1.reg)));

    	    op_size = WORD;
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));	
    	bb->add (SEXT(TEMPREG1, BYTE, VREG(op->op1.reg)));

    	op_size = WORD;
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

}

// 0F BE /r Ia_movsbw_Gw_Eb
void IA32Interpreter::r_rorm_movsbw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (SEXT(VREG(insn->rm), BYTE, TEMPREG2));

    	    //op_size = HALFWORD;
	    bb->add (LI(0xffff0000, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SRL(VREG(insn->rm), TEMPREG1, TEMPREG2));
    	    bb->add (SEXT(TEMPREG2, BYTE, TEMPREG2));

    	    //op_size = HALFWORD;
	    bb->add (LI(0xffff0000, TEMPREG1));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));	
    	bb->add (SEXT(TEMPREG1, BYTE, TEMPREG1));

    	//op_size = HALFWORD;
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

}

//C7 Ia_movl_Ed_Id
void IA32Interpreter::rorm_i_movlc7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
    	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));	
    }
}

//C7 Ia_movl_Ew_Iw
void IA32Interpreter::rorm_i_movwc7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb )
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
    	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));	
    }
}

//76 Ia_jbe_Jb  Note:jbe is the same of jna   (CF==1 or ZF==1)
void IA32Interpreter::i_jbed(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    i_jbeb(insn,op,bb);
}

//0F 86 Ia_jbe_Jd  Note:jbe is the same of jna   (CF==1 or ZF==1)
void IA32Interpreter::i_jbeb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    bb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG2));
    bb->add(OR(TEMPREG1, TEMPREG2, TEMPREG1));
    bb->add(BRANCH(GT, TEMPREG1, 0, 0, op->op1.imm));
}

//77 Ia_jnbe_Jb  Note:jnbe is the same of ja   (CF==0 && ZF==0)
void IA32Interpreter::i_jnbeb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    bb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG2));
    bb->add(OR(TEMPREG1, TEMPREG2, TEMPREG1));
    bb->add(BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));
}

//0F 87 Ia_jnbe_Jd 
void IA32Interpreter::i_jnbed(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    i_jnbeb(insn, op, bb);
}

//7D Ia_jnl_Jb  Note:jnl is the same of jge   (OF==SF)
void IA32Interpreter::i_jnlb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add(BRANCH(EQ, TEMPREG1, TEMPREG2, 0, op->op1.imm));
}

// 0f 8d
void IA32Interpreter::i_jnld(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add(BRANCH(EQ, TEMPREG1, TEMPREG2, 0, op->op1.imm));	
}

//7F Ia_jnle_Jb  Note:jnle is the same of jg   (OF==SF && ZF==0)
void IA32Interpreter::i_jnleb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG3));
    bb->add(CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG4));
    bb->add(BRANCH(LT, TEMPREG3, TEMPREG4, 0, op->op1.imm));	
}

// 0f 8f
void IA32Interpreter::i_jnled(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::OF, TEMPREG1));
    bb->add(IA32GET(IA32ProcessorState::SF, TEMPREG2));
    bb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG3));
    bb->add(CMP(EQ, TEMPREG1, TEMPREG2, TEMPREG4));
    bb->add(BRANCH(LT, TEMPREG3, TEMPREG4, 0, op->op1.imm));
}

//0F 95 Ia_setnz_Eb
void IA32Interpreter::rorm_setnz(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::ZF, TEMPREG1));

    //op_size = BYTE;
    bb->add(CMP(EQ, TEMPREG1, 0, TEMPREG2));
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

	    bb->add (LI(0x8, TEMPREG1));
	    bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
}

// 0D id Ia_orl_EAX_id
void IA32Interpreter::EAX_i_orl0d(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(IA32ProcessorState::EAX)));

    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//09 /r Ia_orl_Ed_Gd
void IA32Interpreter::rorm_r_orl09(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
    	bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));

	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (OR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
    	bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG1));

	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//09 /r Ia_orw_Ew_Gw
void IA32Interpreter::rorm_r_orw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), VREG(op->op2.reg), TEMPREG1));
	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG1));
	bb->add (OR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (ST(TEMPREG1, HALFWORD, t, mm_->map(0)));
    }
}

//08 /r Ia_orb_Eb_Gb
void IA32Interpreter::rorm_r_orb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op2.reg < 4)
	{
	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (OR(VREG(op->op2.reg), VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -= 4;
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (OR(VREG(op->op2.reg), TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
	else
	{
	    op->op2.reg -= 4;

	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	    else
	    {
		insn->rm -=4;

    		bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (OR(TEMPREG1, TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
		bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    		bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	    }
	}
    }
    else
    {
	XTRegNum t = resolveModRM(insn,op,bb);

	if (op->op2.reg < 4)
	{
    	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (OR(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
	else
	{
	    op->op2.reg -= 4;

 	    bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG3));
    	    bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
    	    bb->add (OR(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

    	    bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
	}
    }

}

// 0A /r Ia_orb_Gb_Eb
void IA32Interpreter::r_rorm_orb0a(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (op->op1.reg < 4)
	{
	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (OR(VREG(op->op1.reg), VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -=4;
    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (OR(VREG(op->op1.reg), TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (LI(0xffffff00, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
	else
	{
	    op->op1.reg -= 4;

	    if (insn->rm < 4)
	    {
    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    		bb->add (OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	    else
	    {
		insn->rm -=4;

    		bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
		bb->add (LI(0x8, TEMPREG2));
		bb->add (SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG1));
    		bb->add (IA32GET(insn->rm, VREG(insn->rm)));
		bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    		bb->add (OR(TEMPREG1, TEMPREG3, TEMPREG1));
    		bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

		bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
		bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
		bb->add (LI(0xffff00ff, TEMPREG2));
		bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
		bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    		bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	    }
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));

	if (op->op1.reg < 4)
	{
    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    	    bb->add (OR(TEMPREG1, VREG(op->op1.reg), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
	else
	{
	    op->op1.reg -= 4;

    	    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(op->op1.reg), TEMPREG2, TEMPREG3));
    	    bb->add (OR(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	    bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
    	    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
	}
    }

    /*
    op_size = BYTE;
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
        bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(op->op1.reg)));

	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(op->op1.reg)));

	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    */
}

//80 /1 Ia_orb_Eb_Ib
void IA32Interpreter::rorm_i_orb80(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (LI((Word)op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (LI((Word)op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG2));
	    bb->add (SRL(VREG(insn->rm), TEMPREG2, TEMPREG3));
    	    bb->add (OR(TEMPREG1, TEMPREG3, TEMPREG1));
    	    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (SLL(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI((Word)op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
    	bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG2));

	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }

    /*
    op_size = BYTE;
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(insn->rm)));

	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG2));

	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));
    }
    */
}

//81 /1 Ia_orl_Ed_Id
void IA32Interpreter::rorm_i_orl81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    rorm_i_orl83(insn, op, bb);
}

//83 /1 Ia_orl_Ed_sIb
void IA32Interpreter::rorm_i_orl83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(insn->rm)));

	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

// 81 Ia_orw_Ew_Iw
void IA32Interpreter::rorm_i_orw81(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1,TEMPREG2));

	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//83 Ia_orw_Ew_sIb
void IA32Interpreter::rorm_i_orw83(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(TEMPREG1, VREG(insn->rm), TEMPREG1));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

	bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	bb->add (LI(0xffff0000, TEMPREG2));
	bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (OR(TEMPREG2, TEMPREG1, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_andw), 1,TEMPREG2));

	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//0b Ia_orl_Gd_Ed
void IA32Interpreter::rorm_i_orl0b(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (OR(VREG(op->op1.reg), VREG(insn->rm), VREG(op->op1.reg)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));
	
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (OR(VREG(op->op1.reg), TEMPREG1, VREG(op->op1.reg)));
        bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(op->op1.reg)));

	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// 0C ib Ia_orb_AL_Ib
void IA32Interpreter::AL_i_orb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, TEMPREG1));

    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
    bb->add (LI(0xffffff00, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));

    /*
    op_size = BYTE;
    bb->add (LI(op->op2.imm, TEMPREG1));
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    bb->add (CALL((Word)(&crossbit::set_flags_andb), 1, VREG(IA32ProcessorState::EAX)));
    */
}

//73 cb Ia_jnb_Jb  Note:jnb is the same of jae   (CF==0)
void IA32Interpreter::i_jnbb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    bb->add(BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));	
}

//0F 83 cw Ia_jnb_Jd  Note:jnb is the same of jae   (CF==0)
void IA32Interpreter::i_jnbd(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32GET(IA32ProcessorState::CF, TEMPREG1));
    bb->add(BRANCH(EQ, TEMPREG1, 0, 0, op->op1.imm));	
}

//90 Ia_nop
void IA32Interpreter::nop(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
}

//C1 /4 ib Ia_shll_Ed_Ib
void IA32Interpreter::rorm_i_shllc1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));	
        bb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, TEMPREG2, TEMPREG1));

	bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));	
    }
}

//D1 /4 Ia_shll_Ed
void IA32Interpreter::shlld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(1, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));	
        bb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, TEMPREG2, TEMPREG1));

	bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));	
    }
}

// 0f a5
void IA32Interpreter::shldl_cl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("shldl_cl\n");
    // exit(0);
    /*
    XTRegNum t = resolveModRM(insn, op, bb);
    op_size = BYTE;
    bb->add (IA32GET(IA32ProcessorState::ECX, t2));
    bb->add (ZEXT(t2, BYTE, t2));
    op_size = WORD;
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, t3));
	bb->add (SLL(t3, t2, t4));
	bb->add (IA32PUT(t4, insn->rm));
	bb->add (LI(32, t1));
	bb->add (SUB(t1, t2, t1));
	bb->add (IA32GET(op->op2.reg, t2));
	bb->add (SRL(t2, t1, t2));
	bb->add (IA32GET(insn->rm,t1));
	bb->add (OR(t1, t2, t3));
	bb->add (IA32PUT(t3, insn->rm));
    }
    else
    {
	printf("in shldl_c1\n");
	exit(0);
	bb->add (LD(t, mm_->map(0), WORD, t3));
	bb->add (SLL(t3, t2, t4));
	bb->add (ST(t4, WORD, t, mm_->map(0)));
    }
    */
    if (insn->mod == 3)
    {
	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LI(0xff, TEMPREG1));
	bb->add (AND(VREG(IA32ProcessorState::ECX), TEMPREG1, VREG(IA32ProcessorState::ECX)));

    	bb->add (LI (32, TEMPREG1));
    	bb->add (SUB(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	bb->add (SRL(VREG(op->op2.reg), TEMPREG1, VREG(op->op2.reg)));

	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (MOV(VREG(op->op1.reg), TEMPREG1));
	// bb->add (LI (op->op3.imm, t3));
	bb->add (SLL(VREG(op->op1.reg), VREG(IA32ProcessorState::ECX), VREG(op->op1.reg)));
	bb->add (OR (VREG(op->op1.reg), VREG(op->op2.reg), VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    	bb->add (CALL((Word)(&crossbit::set_flags_shldl),3, TEMPREG1, VREG(op->op1.reg), VREG(IA32ProcessorState::ECX)));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);

	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LI(0xff, TEMPREG1));
	bb->add (AND(VREG(IA32ProcessorState::ECX), TEMPREG1, VREG(IA32ProcessorState::ECX)));

    	bb->add (LI (32, TEMPREG1));
    	bb->add (SUB(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	bb->add (SRL(VREG(op->op2.reg), TEMPREG1, VREG(op->op2.reg)));

	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));	// M[t2] = t1
	bb->add (SLL(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG2));
	bb->add (OR (TEMPREG2, VREG(op->op2.reg), TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));	// M[t2] = t1

    	bb->add (CALL((Word)(&crossbit::set_flags_shldl),3, TEMPREG1, TEMPREG2, VREG(IA32ProcessorState::ECX)));
    }

 
    //bb->add (LI((Word)state_, t4));
    //bb->add (CALL((Word)(&crossbit::set_flags_shll),3,t4,t3,t2));
}

// Added by zhengjuyu
// There is a bug here, the eflags is wrong.
// 0f a4
void IA32Interpreter::rorm_r_i_shldl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("shld\n");
    op_size = WORD;
    if (insn->mod == 3)
    {
        bb->add (LI(op->op3.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (SLL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	//bb->add (IA32PUT(t4, insn->rm));
	bb->add (LI(32, TEMPREG2));
	bb->add (SUB(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (SRL(VREG(op->op2.reg), TEMPREG2, TEMPREG1));
	//bb->add (IA32GET(insn->rm,t1));
	bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
	printf("in shldl_c1\n");
	exit(0);
	bb->add (LD(t, mm_->map(0), WORD, t3));
	bb->add (SLL(t3, t2, t4));
	bb->add (ST(t4, WORD, t, mm_->map(0)));
    }
 
}

// Added by zhengjuyu
// There is a bug here, the eflags is wrong.
// 0f a5
void IA32Interpreter::shrdl_cl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("shrd\n");
    bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    bb->add (LI(0x1f, TEMPREG1));
    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (SRL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (CMP(NE, 0, TEMPREG1, TEMPREG2));
	bb->add (SUB(0, TEMPREG2, TEMPREG2));
	bb->add (LI(32, TEMPREG3));
	bb->add (SUB(TEMPREG3, TEMPREG1, TEMPREG3));
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (AND(TEMPREG2, VREG(op->op2.reg), TEMPREG2));
	bb->add (SLL(TEMPREG2, TEMPREG3, TEMPREG2));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
	printf("shrdl_c1\n");
	exit(0);
	bb->add (LD(t, mm_->map(0), WORD, t3));
	bb->add (SRL(t3, t2, t4));
	bb->add (ST(t4, WORD, t, mm_->map(0)));
    }
}

// Added by zhengjuyu
//
void IA32Interpreter::sahf(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    /*
    bb->add (IA32GET(IA32ProcessorState::EAX, t1));
    bb->add (LI(0x100, t2));
    bb->add (AND(t2, t1, t2));
    bb->add (CMP(NE, t2, 0, t3));
    bb->add (IA32PUT(t3, IA32ProcessorState::CF));

    bb->add (LI(0x400, t2));
    bb->add (AND(t2, t1, t2));
    bb->add (CMP(NE, t2, 0, t3));
    bb->add (IA32PUT(t3, IA32ProcessorState::PF));

    bb->add (LI(0x1000, t2));
    bb->add (AND(t2, t1, t2));
    bb->add (CMP(NE, t2, 0, t3));
    bb->add (IA32PUT(t3, IA32ProcessorState::AF));

    bb->add (LI(0x4000, t2));
    bb->add (AND(t2, t1, t2));
    bb->add (CMP(NE, t2, 0, t3));
    bb->add (IA32PUT(t3, IA32ProcessorState::ZF));

    bb->add (LI(0x8000, t2));
    bb->add (AND(t2, t1, t2));
    bb->add (CMP(NE, t2, 0, t3));
    bb->add (IA32PUT(t3, IA32ProcessorState::SF));
    */
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (CALL((Word)(&crossbit::set_flags_sahf), 1, VREG(IA32ProcessorState::EAX)));
}

// Added by zhengjuyu
// a bug here
void IA32Interpreter::bsfl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, t2));
	bb->add (CMP(EQ, t2, 0, t3));
	bb->add (IA32PUT(t3, IA32ProcessorState::ZF));
	bb->add (BSF(t2, t3));
	bb->add (IA32PUT(t3, op->op1.reg));
	printf("bsrl\n");
	exit(0);
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CMP(EQ, TEMPREG1, 0, TEMPREG2));
	bb->add (IA32PUT(TEMPREG2, IA32ProcessorState::ZF));
        bb->add (BSF(TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

// A bug here, it doesn't set the eflag
void IA32Interpreter::bsrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (CMP(EQ, VREG(insn->rm), 0, TEMPREG1));
	bb->add (IA32PUT(TEMPREG1, IA32ProcessorState::ZF));
	bb->add (BSR(VREG(insn->rm), VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
        XTRegNum t = resolveModRM(insn, op, bb);
        bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (CMP(EQ, TEMPREG1, 0, TEMPREG2));
	bb->add (IA32PUT(TEMPREG2, IA32ProcessorState::ZF));
        bb->add (BSR(TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//D3 /7 Ia_sarl_Ed_CL
void IA32Interpreter::rorm_CL_sarl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    	bb->add (LI(0x1f, TEMPREG1));
    	bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	bb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRA(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    	bb->add (LI(0x1f, TEMPREG1));
    	bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
    	bb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, TEMPREG2, TEMPREG1));

	bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

//D1 /7 Ia_sarl_Ed
void IA32Interpreter::sarld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(1, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRA(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, TEMPREG2, TEMPREG1));

	bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

void IA32Interpreter::sarw_i1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;
    if (insn->mod == 3)
    {
        bb->add (LI(1, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (SEXT(VREG(insn->rm), HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_sarw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn, op, bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (SEXT(TEMPREG2, HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_sarw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

//C1 /7 ib Ia_sarl_Ed_Ib
void IA32Interpreter::rorm_i_sarlc1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRA(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));	
        bb->add (CALL((Word)(&crossbit::set_flags_sarl1), 2, TEMPREG2, TEMPREG1));

	bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));	
    }
}

//
void IA32Interpreter::rorm_i_sarbc0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (LI(op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (SEXT(VREG(insn->rm), BYTE, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_sarb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (LI(op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
    	    bb->add (SEXT(TEMPREG2, BYTE, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_sarb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (SLL(TEMPREG2, TEMPREG3, TEMPREG2));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (SEXT(TEMPREG2, BYTE, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_sarb), 2, TEMPREG2, TEMPREG1));

	bb->add (SRA(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));	
    }

}

//D3 /4 ib Ia_shll_Ed_CL
void IA32Interpreter::rorm_r_shlld3(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, VREG(insn->rm), VREG(op->op2.reg)));

	bb->add (SLL(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));	
        bb->add (CALL((Word)(&crossbit::set_flags_shll1), 2, TEMPREG1, VREG(op->op2.reg)));

	bb->add (SLL(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));	
    }
}

//D1 /5 Ia_shrl_Ed
void IA32Interpreter::rorm_shrld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(1, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));	
        bb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));	
    }
}

//D3 /4 ib Ia_shll_Ed_CL
void IA32Interpreter::rorm_r_shrld3(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, VREG(insn->rm), VREG(op->op2.reg)));

	bb->add (SRL(VREG(insn->rm), VREG(op->op2.reg), VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));	
        bb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, TEMPREG1, VREG(op->op2.reg)));

	bb->add (SRL(TEMPREG1, VREG(op->op2.reg), TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));	
    }
}

//C1 /5 ib Ia_shrl_Ed_Ib
void IA32Interpreter::rorm_i_shrlc1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
        bb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, VREG(insn->rm), TEMPREG1));

	bb->add (SRL(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));	
        bb->add (CALL((Word)(&crossbit::set_flags_shrl1), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

// D1 Ia_shlw_Ew_I1
void IA32Interpreter::rorm_shlw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{

    if (insn->mod == 3)
    {
        bb->add (LI(1, TEMPREG1));

	//op_size = HALFWORD;
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (ZEXT(VREG(insn->rm), HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shlw), 2, TEMPREG2, TEMPREG1));

	bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));	
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shlw), 2, TEMPREG2, TEMPREG1));

	bb->add (SLL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

// D0 /5 Ia_shrb_Eb
void IA32Interpreter::rorm_shrb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (LI(1, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (ZEXT(VREG(insn->rm), BYTE, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (LI(1, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
    	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (SLL(TEMPREG2, TEMPREG3, TEMPREG2));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));	
    }

}

// C0 /5 ib Ia_shrb_Eb_Ib
void IA32Interpreter::shrb_ib(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (LI(op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (ZEXT(VREG(insn->rm), BYTE, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (LI(0xffffff00, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (LI(op->op2.imm, TEMPREG1));
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	    bb->add (LI(0x8, TEMPREG3));
	    bb->add (SRL(VREG(insn->rm), TEMPREG3, TEMPREG2));
    	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
    	    bb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

    	    bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	    bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
	    bb->add (SLL(TEMPREG2, TEMPREG3, TEMPREG2));
	    bb->add (LI(0xffff00ff, TEMPREG1));
	    bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, BYTE, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shrb), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, BYTE, t, mm_->map(0)));	
    }
}

// D1 /5 Ia_shrw_Ew
void IA32Interpreter::shrw_i1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(1, TEMPREG1));

	//op_size = HALFWORD;
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (ZEXT(VREG(insn->rm), HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
        bb->add (LI(1, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));	
    }
}

// C1 /5 ib Ia_shrw_Ew_Ib
void IA32Interpreter::shrw_ib(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
        bb->add (LI(op->op2.imm, TEMPREG1));

	//op_size = HALFWORD;
	bb->add (IA32GET(insn->rm, VREG(insn->rm)));
	bb->add (ZEXT(VREG(insn->rm), HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (LI(0xffff0000, TEMPREG1));
	bb->add (AND(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
	bb->add (OR(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	bb->add (IA32PUT(VREG(insn->rm), insn->rm));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LI(op->op2.imm, TEMPREG1));
	bb->add (LD(t, mm_->map(0), HALFWORD, TEMPREG2));	
	bb->add (ZEXT(TEMPREG2, HALFWORD, TEMPREG2));
        bb->add (CALL((Word)(&crossbit::set_flags_shrw), 2, TEMPREG2, TEMPREG1));

	bb->add (SRL(TEMPREG2, TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, HALFWORD, t, mm_->map(0)));
    }
}

void IA32Interpreter::rorm_notb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	if (insn->rm < 4)
	{
    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (NOT(VREG(insn->rm), TEMPREG1));
	    bb->add (ZEXT(TEMPREG1, BYTE, TEMPREG1));
	    bb->add (LI(0xffffff00, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
	else
	{
	    insn->rm -= 4;

    	    bb->add (IA32GET(insn->rm, VREG(insn->rm)));
    	    bb->add (NOT(VREG(insn->rm), TEMPREG1));
	    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
	    bb->add (LI(0xff00, TEMPREG2));
	    bb->add (AND(TEMPREG1, TEMPREG2, TEMPREG1));
	    bb->add (LI(0xffff00ff, TEMPREG2));
	    bb->add (AND(VREG(insn->rm), TEMPREG2, VREG(insn->rm)));
	    bb->add (OR(VREG(insn->rm), TEMPREG1, VREG(insn->rm)));
    	    bb->add (IA32PUT(VREG(insn->rm), insn->rm));
	}
    }
    else
    {
        XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (NOT(TEMPREG1, TEMPREG1));
	bb->add (ST(TEMPREG1, BYTE, t, mm_->map(0)));
    }

}

//F7 /2 Ia_notl_Ed
void IA32Interpreter::rorm_notl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add(NOT(VREG(op->op1.reg), VREG(op->op1.reg)));
	bb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (NOT(TEMPREG1, TEMPREG2));
	bb->add (ST(TEMPREG2, WORD, t, mm_->map(0)));
    }
}

//F7 /3 Ia_negl_Ed
//Note:This operation is equivalent to subtracting the operand from 0.
void IA32Interpreter::rorm_negl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(LI(0, TEMPREG1));
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    	bb->add (CALL((Word)(&crossbit::set_flags_negl),1, VREG(op->op1.reg)));
	bb->add (SUB(TEMPREG1, VREG(op->op1.reg), VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
    	bb->add (CALL((Word)(&crossbit::set_flags_negl), 1, TEMPREG2));
	bb->add (SUB(TEMPREG1, TEMPREG2, TEMPREG1));
	bb->add (ST(TEMPREG1, WORD, t, mm_->map(0)));
    }
}

//F7 /6 Ia_divl_EAX_Ed
void IA32Interpreter::EAX_rorm_divl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
    	bb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    	bb->add(IA32GET(IA32ProcessorState::EDX, VREG(IA32ProcessorState::EDX)));
	bb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add(DIVU64(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX), VREG(op->op2.reg),
		    TEMPREG2, TEMPREG3));
	bb->add(MOV(TEMPREG2, VREG(IA32ProcessorState::EAX)));
	bb->add(MOV(TEMPREG3, VREG(IA32ProcessorState::EDX)));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
    	bb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    	bb->add(IA32GET(IA32ProcessorState::EDX, VREG(IA32ProcessorState::EDX)));
	bb->add(DIVU64(VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX), TEMPREG1,
		    TEMPREG2, TEMPREG3));
	bb->add(MOV(TEMPREG2, VREG(IA32ProcessorState::EAX)));
	bb->add(MOV(TEMPREG3, VREG(IA32ProcessorState::EDX)));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
}

// There is a bug here, the DIV is defined as EDX:EAX / src,
// But now there is only EAX / src
// added by zhengjuyu
// f7
void IA32Interpreter::idivf7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{

    if (insn->mod == 3)
    {
	bb->add(IA32GET(insn->rm, VREG(insn->rm)));
	bb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add(DIV(VREG(IA32ProcessorState::EAX), VREG(insn->rm), VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX)));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add (DIV(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX), VREG(IA32ProcessorState::EDX)));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
}

// added by zhengjuyu
// f7
void IA32Interpreter::imulf7(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add(IA32GET(insn->rm, VREG(insn->rm)));
	bb->add(IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add(MUL(VREG(IA32ProcessorState::EAX), VREG(insn->rm), VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
	bb->add(IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add (MUL(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EDX), IA32ProcessorState::EDX));
    }
    bb->add(CALL((Word)(&crossbit::set_flags_imull), 1, VREG(IA32ProcessorState::EDX)));
}


//There maybe a bug here.
//added by Chuchao
//0F AF Ia_imull_Gw_Ew
void IA32Interpreter::r_rorm_imulw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("r_rorm_imulw: 0x%08x\n", op->op3.imm);
    
    op_size = HALFWORD;

    if (insn->mod == 3)
    {
	bb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add(MUL(VREG(op->op1.reg), VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (MUL(VREG(op->op1.reg), TEMPREG1, TEMPREG2, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
    }

    bb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG2));
}

//0F AF Ia_imull_Gd_Ed
void IA32Interpreter::r_rorm_imull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add(IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add(MUL(VREG(op->op1.reg), VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (MUL(VREG(op->op1.reg), TEMPREG1, TEMPREG2, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
    }

    bb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG2));
}


// 69 /r id 
void IA32Interpreter::imull_id(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(LI(op->op3.imm, TEMPREG1));
    if (insn->mod == 3)
    {
	bb->add(IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add(MUL(VREG(op->op2.reg), TEMPREG1, TEMPREG3, VREG(op->op1.reg)));
	bb->add(IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG2));
	bb->add (MUL(TEMPREG2, TEMPREG1, TEMPREG3, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }

    bb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG3));
}

//6B Ia_imull_Gd_Ed_sIb
void IA32Interpreter::r_rorm_i_imull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(LI(op->op3.imm, TEMPREG1));
    if (insn->mod == 3)
    {
	bb->add(IA32GET(op->op2.reg ,VREG(op->op2.reg)));
	bb->add(MUL(TEMPREG1, VREG(op->op2.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add(IA32PUT(VREG(op->op1.reg) ,op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG3));
	bb->add (MUL(TEMPREG1, TEMPREG3, TEMPREG2, VREG(op->op1.reg)));
	bb->add(IA32PUT(VREG(op->op1.reg) ,op->op1.reg));
    }
    bb->add(CALL((Word)(&crossbit::set_flags_imull),1, TEMPREG2));

}

//F7 /4 Ia_mull_EAX_Ed
void IA32Interpreter::EAX_rorm_mull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{ 
    if (insn->mod == 3)
    {
	bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (MULU(VREG(IA32ProcessorState::EAX), VREG(op->op2.reg), VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));
	bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
	bb->add (MULU(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EDX), VREG(IA32ProcessorState::EAX)));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EAX),IA32ProcessorState::EAX));
	bb->add (IA32PUT(VREG(IA32ProcessorState::EDX),IA32ProcessorState::EDX));
    }
    bb->add (CALL((Word)(&crossbit::set_flags_imull),1, VREG(IA32ProcessorState::EDX)));
}

//FC Ia_cld
void IA32Interpreter::cld(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add(IA32PUT(0, IA32ProcessorState::DF));
}

//A4 Ia_movsb_Yb_Xb
void IA32Interpreter::m_m_movsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    bb->add (USE(IA32ProcessorState::ESI));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
	bb->add (LABEL(0));
    }

    // There may be a bug here!
    bb->add (LD(VREG(IA32ProcessorState::ESI), mm_->map(0), BYTE, TEMPREG1));
    bb->add (ADDI(VREG(IA32ProcessorState::ESI), 1, VREG(IA32ProcessorState::ESI)));
    bb->add (ST(TEMPREG1, BYTE, VREG(IA32ProcessorState::EDI), mm_->map(0)));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
    	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));
       	bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	bb->add (LOOPN(VREG(IA32ProcessorState::ECX), 0, 0));

	hasRep = false;
	bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

// A6 Ia_cmpsb_Yb_Xb
void IA32Interpreter::cmpsb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));
    bb->add (IA32GET(IA32ProcessorState::ESI, VREG(IA32ProcessorState::ESI)));
    bb->add (USE(IA32ProcessorState::ESI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
	bb->add (LABEL(0));
    }

    bb->add (LD(VREG(IA32ProcessorState::EDI), mm_->map(0), WORD, TEMPREG1));
    bb->add (LD(VREG(IA32ProcessorState::ESI), mm_->map(0), WORD, TEMPREG2));
    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, TEMPREG2, TEMPREG1));

    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));
    bb->add (ADDI(VREG(IA32ProcessorState::ESI), 1, VREG(IA32ProcessorState::ESI)));

    if (hasRep)
    {
	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));

	if (repFlag == 1)
	{
	    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
	    bb->add (SUBI(TEMPREG1, 1, TEMPREG1));
	    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
	    bb->add (LOOPN(TEMPREG1, 0, 0));
	    bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	}
	else
	{
	    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
	    bb->add (NOT(TEMPREG1, TEMPREG1));
	    bb->add (ADDI(TEMPREG1, 1, TEMPREG1));
	    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
	    bb->add (LOOPN(TEMPREG1, 0, 0));
	    bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	}

	hasRep = false;
	bb->add (LABEL(1));
    }

    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESI), IA32ProcessorState::ESI));
}

//AE Ia_scasb_Yb_AL
void IA32Interpreter::m_r_scasb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = WORD;

    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (USE(IA32ProcessorState::EAX));
    bb->add (IA32GET(IA32ProcessorState::EDI, VREG(IA32ProcessorState::EDI)));
    bb->add (USE(IA32ProcessorState::EDI));

    if (hasRep)
    {
    	bb->add (IA32GET(IA32ProcessorState::ECX, VREG(IA32ProcessorState::ECX)));
	bb->add (LOOP(VREG(IA32ProcessorState::ECX), 1, 1));
	bb->add (LABEL(0));
    }

    bb->add (LD(VREG(IA32ProcessorState::EDI), mm_->map(0), WORD, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_subb), 2, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (ADDI(VREG(IA32ProcessorState::EDI), 1, VREG(IA32ProcessorState::EDI)));
    if (hasRep)
    {
	bb->add (SUBI(VREG(IA32ProcessorState::ECX), 1, VREG(IA32ProcessorState::ECX)));

	if (repFlag == 1)
	{
	    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
	    bb->add (SUBI(TEMPREG1, 1, TEMPREG1));
	    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
	    bb->add (LOOPN(TEMPREG1, 0, 0));
	    bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	}
	else
	{
	    bb->add (IA32GET(IA32ProcessorState::ZF, TEMPREG1));
	    bb->add (NOT(TEMPREG1, TEMPREG1));
	    bb->add (ADDI(TEMPREG1, 1, TEMPREG1));
	    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::ECX), TEMPREG1));
	    bb->add (LOOPN(TEMPREG1, 0, 0));
	    bb->add (IA32PUT(VREG(IA32ProcessorState::ECX), IA32ProcessorState::ECX));
	}

	hasRep = false;
	bb->add (LABEL(1));
    }
    
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EDI), IA32ProcessorState::EDI));
}

//C9 Ia_leave
void IA32Interpreter::leave(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EBP, VREG(IA32ProcessorState::EBP)));
    bb->add (MOV(VREG(IA32ProcessorState::EBP), VREG(IA32ProcessorState::ESP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));

    bb->add (IA32GET(IA32ProcessorState::ESP, VREG(IA32ProcessorState::ESP)));
    bb->add (LD(VREG(IA32ProcessorState::ESP), mm_->map(0), WORD, VREG(IA32ProcessorState::EBP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EBP), IA32ProcessorState::EBP));
    //bb->add (LI(4, TEMPREG1));
    //bb->add (ADD(VREG(IA32ProcessorState::ESP), TEMPREG1, VREG(IA32ProcessorState::ESP)));
    bb->add (ADDI(VREG(IA32ProcessorState::ESP), 4, VREG(IA32ProcessorState::ESP)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::ESP), IA32ProcessorState::ESP));
}

//86 Ia_xchgb_Eb_Gb
void IA32Interpreter::r_rorm_xchgb(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    op_size = BYTE;
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (MOV(VREG(op->op2.reg), TEMPREG1));
	bb->add (MOV(VREG(op->op1.reg), VREG(op->op2.reg)));
	bb->add (MOV(TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
    	XTRegNum t = resolveModRM(insn,op,bb);

	bb->add (LD(t, mm_->map(0), BYTE, TEMPREG1));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (ST(VREG(op->op1.reg), op_size, t, mm_->map(0)));

	bb->add (MOV(TEMPREG1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
}

//87 Ia_xchgl_Ed_Gd
void IA32Interpreter::rorm_r_xchgl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));

	bb->add (MOV(VREG(op->op2.reg), TEMPREG1));
	bb->add (MOV(VREG(op->op1.reg), VREG(op->op2.reg)));
	bb->add (MOV(TEMPREG1, VREG(op->op1.reg)));

	bb->add (IA32PUT(VREG(op->op1.reg),op->op1.reg));
	bb->add (IA32PUT(VREG(op->op2.reg),op->op2.reg));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));	
	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
	bb->add (ST(VREG(op->op2.reg), op_size, t, mm_->map(0)));	
	
	bb->add (MOV(TEMPREG1, VREG(op->op2.reg)));
	bb->add (IA32PUT(VREG(op->op2.reg), op->op2.reg));
    }
}

//49 Ia_decl_ERX
void IA32Interpreter::r_decl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
    //bb->add (LI(1, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_decl1), 1, VREG(op->op1.reg)));

    bb->add (SUBI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
    bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
}

// FF Ia_decl_Ed
void IA32Interpreter::m_decl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    if (insn->mod == 3)
    {
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	//bb->add (LI(1, TEMPREG1));
    	bb->add (CALL((Word)(&crossbit::set_flags_decl1), 1, VREG(op->op1.reg)));

	bb->add (SUBI(VREG(op->op1.reg), 1, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);
	bb->add (LD(t, mm_->map(0), op_size, TEMPREG1));
	//bb->add (LI(1, TEMPREG2));
	bb->add (CALL((Word)(&crossbit::set_flags_decl1), 1, TEMPREG1));

	bb->add (SUBI(TEMPREG1, 1, TEMPREG1));
	bb->add (ST(TEMPREG1, op_size, t, mm_->map(0)));
    }
}

// The Float Control word is unused now!
// So the FPU may not perform well in some case!
void IA32Interpreter::f_fnstcw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("f_fnstcw: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (IA32GET(IA32ProcessorState::FControl,t2));
    bb->add (ST(t2,HALFWORD,t,mm_->map(0)));
}

// The Float Control word is unused now!
// So the FPU may not perform well in some case!
void IA32Interpreter::f_fldcw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("f_fldcw: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(t,mm_->map(0),HALFWORD,t2));
    bb->add (IA32PUT(t2, IA32ProcessorState::FControl));	
}

// Added by zhengjuyu
// frndint
void IA32Interpreter::frndint(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("frndint: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FRNDINT());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// fildl
void IA32Interpreter::fildl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("fildl: 0x%08x\n", op->op3.imm);
    // printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (SUB(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));

    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));
}

// Added by zhengjuyu
// fildq
void IA32Interpreter::fildq(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fildq: 0x%08x\n", op->op3.imm);
    //top = (top - 1) % 8;
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (SUB(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));

    bb->add (FLD(t, mm_->map(0), DWORD, t2));
    bb->add (FCONV(t2, DWORD, t2, DOUBLE));
}

// Added by zhengjuyu
// filds
void IA32Interpreter::filds(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("filds\n");
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (SUB(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));

    bb->add (FLD(t, mm_->map(0), WORD, t2));
    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FCONV(t2, HALFWORD, t2, DOUBLE));
}

// Added by zhengjuyu
// fimull
void IA32Interpreter::fimull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fimull: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FMULD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fchs
void IA32Interpreter::fchs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FCHS());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// fadds
void IA32Interpreter::fadds(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fadds: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FADDD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// faddl
void IA32Interpreter::faddl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("faddl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FGETD(t2));
    bb->add (FADDD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubl
void IA32Interpreter::fsubl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsubl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubrl
void IA32Interpreter::fsubrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fsubrl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t2));
    bb->add (FGETD(t3));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubrs
void IA32Interpreter::fsubrs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fsubrs: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (LI(8, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));

    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FSUBD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fsubs
void IA32Interpreter::fsubs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsubs: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    //bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fisubl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fisubl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FSUBD());
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fisubrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fisubrl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// fabs
void IA32Interpreter::fabs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fabs: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FABSD());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fldl2e(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fldl2e: 0x%08x\n", op->op3.imm);

    bb->add (FLDL2E());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fldlg2(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fldlg2: 0x%08x\n", op->op3.imm);

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (FGETD(t1));
    //bb->add (FABSD());
    bb->add (FLDLG2());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fldln2(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fldln2: 0x%08x\n", op->op3.imm);

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (FGETD(t1));
    //bb->add (FABSD());
    bb->add (FLDLN2());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
void IA32Interpreter::fyl2x(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fyl2x: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FYL2X());

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
void IA32Interpreter::fyl2xp1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fyl2xp1: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FYL2XP1());

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
// faddp
void IA32Interpreter::faddp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("faddp st(%d): 0x%08x\n", insn->rm, op->op3.imm);
    // printf("top: %d\n", top);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FADDD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// fiaddl
void IA32Interpreter::fiaddl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fiaddl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    //bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FADDD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fadd_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fadd_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FADDD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fadd_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fadd_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FADDD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsub_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsub_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t1));
    bb->add (FGETD(t2));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsubr_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsubr_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by chuchao
// DC E3
void IA32Interpreter::fsubr_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t1));
    bb->add (FGETD(t2));
    bb->add (FSUBD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsub_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsub_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FSUBD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsubp_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //no verify
    //printf("fsubp_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FSUBD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fsubrp_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fsubrp_st0_sti st(%d)\n", insn->rm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t1));
    bb->add (FGETD(t2));
    bb->add (FSUBD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmul_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fmul_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FMULD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmul_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fmul_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FMULD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmulp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    // printf("fmulp: 0x%08x\n", op->op3.imm); 
    // printf("top: %d\n", top);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FMULD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmull(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fmull: 0x%08x\n", op->op3.imm); 

    XTRegNum t = resolveModRM(insn,op,bb);
 
    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (FGETD(t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FMULD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fmuls(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fmuls: 0x%08x\n", op->op3.imm); 

    XTRegNum t = resolveModRM(insn,op,bb);
 
    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));
    //bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FMULD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
//
void IA32Interpreter::fst_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t1));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
//
void IA32Interpreter::fstp_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fstp st(%d): 0x%08x\n", insn->rm, op->op3.imm);
    //printf("top: %d\n", top);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t1));
    bb->add (FPUTD(t2));
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// fsqrt
void IA32Interpreter::fsqrt(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsqrt: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FSQRTD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// fstl
void IA32Interpreter::fstl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fstl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FST(t2, DOUBLE, t, mm_->map(0)));
}

// Added by zhengjuyu
// fsts
void IA32Interpreter::fsts(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsts: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(8, t3));
    bb->add (FCONV(t2, DOUBLE, t3, FLOAT));
    //bb->add (LI(8, t3));
    bb->add (FST(t3, WORD, t, mm_->map(0)));
}

// Added by zhengjuyu
// fstpl
void IA32Interpreter::fstpl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fstpl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FST(t2, DOUBLE, t, mm_->map(0)));
    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (ADD(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fistl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(8, t3));
    bb->add (FCONV(t2, DOUBLE, t3, WORD));
    //bb->add (LI(8, t3));
    bb->add (FST(t3, WORD, t, mm_->map(0)));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistpl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fistpl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FCONV(t2, DOUBLE, t2, WORD));
    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FST(t2, WORD, t, mm_->map(0)));

    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (ADD(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistps(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fistps: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FCONV(t2, DOUBLE, t2, WORD));

    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    bb->add (LI(offset, t3));
    bb->add (MULU(t2, t3, t4, t5));
    bb->add (LD(t5, state_->fpget(0), HALFWORD, t2));
    bb->add (ST(t2, HALFWORD, t, mm_->map(0)));

    //bb->add (FST(t2, WORD, t, mm_->map(0)));

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (ADD(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fistpll(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fistpll: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FCONV(t2, DOUBLE, t2, DWORD));

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    bb->add (LI(offset, t3));
    bb->add (MULU(t2, t3, t4, t5));
    bb->add (LD(t5, state_->fpget(0), WORD, t2));
    bb->add (ST(t2, WORD, t, mm_->map(0)));
    bb->add (LD(t5, state_->fpget(0) + 4, WORD, t2));
    bb->add (ST(t2, WORD, t, mm_->map(0) + 4));

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (ADD(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));
}

// Added by Chuchao
// d9 fstps
void IA32Interpreter::fstps(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fstps: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(8, t3));
    bb->add (FCONV(t2, DOUBLE, t3, FLOAT));
    //bb->add (LI(8, t3));
    bb->add (FST(t3, WORD, t, mm_->map(0)));

    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (ADD(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));
}

// Added by Chuchao
// dd fldl
void IA32Interpreter::fldl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fldl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn, op, bb);
    
    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (SUB(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));
    //bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
}

// Added by zhengjuyu 
// d9 C0 + i
void IA32Interpreter::fld_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fld_sti: 0x%08x\n", op->op3.imm);
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
    bb->add (FPUTD(t1));
}

// Added by Chuchao
// d9 flds
void IA32Interpreter::flds(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("flds\n");
    //printf("address: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LD(0, (MemAddr)&top, WORD, t2));
    bb->add (LI(1, t3));
    bb->add (SUB(t2, t3, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (ST(t2, WORD, 0, (MemAddr)&top));

    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));
}

// Added by Chuchao
// d9 fldz
void IA32Interpreter::fldz(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fldz: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));

    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    bb->add (LI(offset, t2));
    bb->add (MULU(t1, t2, t3, t4));

    bb->add (ST(0, WORD, t4, state_->fpget(0)));
    bb->add (ST(0, WORD, t4, state_->fpget(0) + 4));
}

// Added by Chuchao
// 
void IA32Interpreter::fld1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fld1\n");
    //printf("top: %d\n", top);
    MemAddr offset = state_->fpget(1) - state_->fpget(0);
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
    bb->add (LI(offset, t2));
    bb->add (MULU(t1, t2, t3, t4));

    bb->add (LI(1, t1));
    bb->add (ST(t1, WORD, t4, state_->fpget(0)));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FCONV(t1, WORD, t1, DOUBLE));
}

// Added by zhengjuyu
//
void IA32Interpreter::fxam(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fxam: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FXAM());
    bb->add (LI(8, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
//
void IA32Interpreter::f2xm1(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("f2xm1: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (F2XM1());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
//
void IA32Interpreter::fscale(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FSCALE());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
    bb->add (LI(8, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
//
void IA32Interpreter::fcos(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fcos: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FCOS());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
//
void IA32Interpreter::fsin(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fsin: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FSIN());
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
//
void IA32Interpreter::fptan(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fptan: 0x%08x\n", op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));
    bb->add (FPTAN());

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (SUB(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
    bb->add (FPUTD(t1));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// dd e9 fucom
void IA32Interpreter::fucom(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fucom st(%d): 0x%08x\n", insn->rm, op->op3.imm);
    
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FCMPD(EQ, t1, t2, 9));
    bb->add (FCMPD(BE, t1, t2, 10));

    bb->add (LD(0, state_->fpget(9), WORD, t1));
    bb->add (LI(14, t2));
    bb->add (SLL(t1, t2, t1));
    bb->add (LD(0, state_->fpget(10), WORD, t2));
    bb->add (LI(8, t3));
    bb->add (SLL(t2, t3, t2));
    bb->add (OR(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, state_->fpget(11)));
}

// Added by Chuchao
// dd e9 fucomp
void IA32Interpreter::fucomp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fucomp st(%d): 0x%08x\n", insn->rm, op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FCMPD(EQ, t1, t2, 9));
    bb->add (FCMPD(BE, t1, t2, 10));

    bb->add (LD(0, state_->fpget(9), WORD, t1));
    bb->add (LI(14, t2));
    bb->add (SLL(t1, t2, t1));
    bb->add (LD(0, state_->fpget(10), WORD, t2));
    bb->add (LI(8, t3));
    bb->add (SLL(t2, t3, t2));
    bb->add (OR(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, state_->fpget(11)));
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

//
void IA32Interpreter::fcompl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fcompl: 0x%08x\n", op->op3.imm);

    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FCMPD(EQ, t1, t2, 9));
    bb->add (FCMPD(BE, t1, t2, 10));

    bb->add (LD(0, state_->fpget(9), WORD, t1));
    bb->add (LI(14, t2));
    bb->add (SLL(t1, t2, t1));
    bb->add (LD(0, state_->fpget(10), WORD, t2));
    bb->add (LI(8, t3));
    bb->add (SLL(t2, t3, t2));
    bb->add (OR(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, state_->fpget(11)));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fucompp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fucompp st(%d): 0x%08x\n", insn->rm, op->op3.imm);
    
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    //bb->add (LI(9, t3));
    bb->add (FCMPD(EQ, t1, t2, 9));
    //bb->add (LI(10, t3));
    bb->add (FCMPD(BE, t1, t2, 10));
    //bb->add (FCMPD(EQ, 6, 7, 9));
    //bb->add (FCMPD(BE, 6, 7, 10));

    bb->add (LD(0, state_->fpget(9), WORD, t1));
    bb->add (LI(14, t2));
    bb->add (SLL(t1, t2, t1));
    bb->add (LD(0, state_->fpget(10), WORD, t2));
    bb->add (LI(8, t3));
    bb->add (SLL(t2, t3, t2));
    bb->add (OR(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, state_->fpget(11)));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(2, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fxch_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fxch st(%d): 0x%08x\n", insn->rm, op->op3.imm);
    //printf("top: %d\n", top);
    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FGETD(t2));
    
    bb->add (LI(8, t4));
    bb->add (FPUTD(t4));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FGETD(t1));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    bb->add (LI(8, t4));
    bb->add (FGETD(t4));

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by Chuchao
// df e0 fnstsw_ax
void IA32Interpreter::fnstsw_ax(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (LD(0, state_->fpget(11), HALFWORD, TEMPREG1));
    //op_size = HALFWORD;
    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
    bb->add (IA32GET(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

// Added by zhengjuyu
// DA
void IA32Interpreter::fidivl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fidivl: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    //bb->add (LI(8, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));

    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FDIVD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdiv_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdiv_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t1));
    bb->add (FGETD(t2));
    bb->add (FDIVD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdiv_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdiv_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FDIVD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdivp_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("top: %d\n", top);
    //printf("fdivp_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FDIVD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdivr_st0_sti(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivr_st0_sti st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t2));
    bb->add (FGETD(t1));
    bb->add (FDIVD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (FPUTD(t1));
}

// Added by zhengjuyu
// 
void IA32Interpreter::fdivr_sti_st0(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivr_sti_st0 st(%d): 0x%08x\n", insn->rm, op->op3.imm); 

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t1));
    bb->add (FGETD(t2));
    bb->add (FDIVD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));
}

// Added by zhengjuyu
void IA32Interpreter::fdivrs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivrs: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));

    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FDIVD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
void IA32Interpreter::fdivs(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivs: 0x%08x\n", op->op3.imm);
    //printf("top: %d\n", top);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, FLOAT, t2, DOUBLE));

    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (FDIVD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// DA
void IA32Interpreter::fidivrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fidirvl: 0x%08x\n", op->op3.imm);
    XTRegNum t = resolveModRM(insn,op,bb);

    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), WORD, t2));
    bb->add (FCONV(t2, WORD, t2, DOUBLE));
    bb->add (LI(8, t2));
    bb->add (FGETD(t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FDIVD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// DA
void IA32Interpreter::fdivrp(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivrp st(i): 0x%08x\n", insn->rm, op->op3.imm);

    bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(insn->rm, t2));
    bb->add (ADD(t2, t1, t2));
    bb->add (LI(0x7, t3));
    bb->add (AND(t2, t3, t2));

    bb->add (FGETD(t1));
    bb->add (FGETD(t2));
    bb->add (FDIVD());

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    //bb->add (LI(insn->rm, t2));
    //bb->add (ADD(t2, t1, t2));
    //bb->add (LI(0x7, t3));
    //bb->add (AND(t2, t3, t2));
    bb->add (FPUTD(t2));

    //bb->add (LD(0, (MemAddr)&top, WORD, t1));
    bb->add (LI(1, t2));
    bb->add (ADD(t1, t2, t1));
    bb->add (LI(0x7, t2));
    bb->add (AND(t1, t2, t1));
    bb->add (ST(t1, WORD, 0, (MemAddr)&top));
}

// Added by zhengjuyu
// DC
void IA32Interpreter::fdivrl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //printf("fdivrl 0x%08x\n", op->op3.imm);

    XTRegNum t = resolveModRM(insn,op,bb);
    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (FGETD(t2));
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (FDIVD());
    //bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

// Added by zhengjuyu
// DC
void IA32Interpreter::fdivl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //no verify
    //printf("fdivl 0x%08x\n", op->op3.imm);

    XTRegNum t = resolveModRM(insn,op,bb);
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FGETD(t3));
    bb->add (LI(8, t2));
    bb->add (FLD(t, mm_->map(0), DOUBLE, t2));
    bb->add (FGETD(t2));
    bb->add (FDIVD());
    bb->add (LD(0, (MemAddr)&top, WORD, t3));
    bb->add (FPUTD(t3));
}

//25 Ia_andw_AX_Iw
void IA32Interpreter::AX_i_andw25(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    //op_size = HALFWORD;

    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (AND(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//0D Ia_orw_AX_Iw
void IA32Interpreter::AX_i_orw(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (OR(TEMPREG1, VREG(IA32ProcessorState::EAX), TEMPREG1));
    bb->add (ZEXT(TEMPREG1, HALFWORD, TEMPREG1));
    bb->add (CALL((Word)(&crossbit::set_flags_andw), 1, TEMPREG1));

    bb->add (LI(0xffff0000, TEMPREG2));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG2, VREG(IA32ProcessorState::EAX)));
    bb->add (OR(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
}

//25 Ia_andl_EAX_Id
void IA32Interpreter::EAX_i_andl25(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    bb->add (IA32GET(IA32ProcessorState::EAX, VREG(IA32ProcessorState::EAX)));
    bb->add (LI (op->op2.imm, TEMPREG1));
    bb->add (AND(VREG(IA32ProcessorState::EAX), TEMPREG1, VREG(IA32ProcessorState::EAX)));
    bb->add (IA32PUT(VREG(IA32ProcessorState::EAX), IA32ProcessorState::EAX));
    bb->add (CALL((Word)(&crossbit::set_flags_andl), 1, VREG(IA32ProcessorState::EAX)));
}

//XXX
//0F AC Ia_shrdl_Ed_Gd_Id
void IA32Interpreter::rorm_r_i_shrdl(x86_insn *insn, x86_operand *op, VBlockBuilder *bb)
{
    /*
    bb->add (LI (op->op3.imm,t1));
    bb->add (LI (32, t2));
    bb->add (SUB(t2,t1,t2));
    bb->add (IA32GET(op->op2.reg,t3));
    bb->add (SLL(t3,t2,t4));

    XTRegNum t = resolveModRM(insn, op, bb);

    if (insn->mod == 3)
    {
	bb->add (IA32GET(insn->rm,t2));
	bb->add (LI (op->op3.imm,t3));
	bb->add (SRL(t2,t3,t5));
	bb->add (OR (t5,t4,t5));
	bb->add (IA32PUT(t5,insn->rm));
    }
    else
    {
	bb->add (LD(t, mm_->map(0), WORD, t2));	// M[t2] = t1
	bb->add (LI (op->op3.imm,t3));
	bb->add (SRL(t2,t3,t5));
	bb->add (OR (t5,t4,t5));
	bb->add (ST(t5, WORD, t, mm_->map(0)));	// M[t2] = t1
    }
    bb->add (LI ((Word)state_, t4));
    bb->add (CALL((Word)(&crossbit::set_flags_shrdl),4,t4,t2,t5,t3));
    */
    // printf("shrd\n");
    if (insn->mod == 3)
    {
	int shift = ((op->op3.imm) & 0x1f);
	int left = 32 - shift;

	bb->add (LI(left, TEMPREG1));
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	bb->add (SLL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));

	bb->add (LI(shift, TEMPREG3));
	bb->add (IA32GET(op->op1.reg, VREG(op->op1.reg)));
	bb->add (MOV(VREG(op->op1.reg), TEMPREG1));
	bb->add (SRL(VREG(op->op1.reg), TEMPREG3, VREG(op->op1.reg)));
	bb->add (OR (VREG(op->op1.reg), TEMPREG2, VREG(op->op1.reg)));
	bb->add (IA32PUT(VREG(op->op1.reg), op->op1.reg));
    	bb->add (CALL((Word)(&crossbit::set_flags_shrdl1),3, TEMPREG1, VREG(op->op1.reg), TEMPREG3));
    }
    else
    {
	XTRegNum t = resolveModRM(insn, op, bb);

	int shift = ((op->op3.imm) & 0x1f);
	int left = 32 - shift;

	bb->add (LI(left, TEMPREG1));
    	bb->add (IA32GET(op->op2.reg, VREG(op->op2.reg)));
    	bb->add (SLL(VREG(op->op2.reg), TEMPREG1, TEMPREG2));

	bb->add (LI(shift, TEMPREG4));
	bb->add (LD(t, mm_->map(0), WORD, TEMPREG1));	// M[t2] = t1
	bb->add (SRL(TEMPREG1, TEMPREG4, TEMPREG3));
	bb->add (OR (TEMPREG3, TEMPREG2, TEMPREG3));
	bb->add (ST (TEMPREG3, WORD, t, mm_->map(0)));	// M[t2] = t1

    	bb->add (CALL((Word)(&crossbit::set_flags_shrdl1), 3, TEMPREG1, TEMPREG3, TEMPREG4));
    }
}

XTMemAddr IA32Interpreter::decode (XTMemAddr pc, VBlockBuilder *bb)
{
	MemAddr next = pc;	      // initialize next pc address
	// MemAddr at = mm_->map(pc); // locate the code address in memory image
	MemAddr at = pc; // locate the code address in memory image
//	printf(" the pc is %x \n ", pc);
	disassembler disasm;
	disasm.set_syntax_intel();

	struct x86_operand op;
	XbitCallbackPtr_t cb;

	struct x86_insn insn(1, 0);

	curNext = next;

	segOver = false;
	op_size = WORD;

	//modified
/*	if(at == 0x809db7f )
	{
		char pp[100];
		scanf("%s",pp);
	}
	*/
	insn = disasm.decode(1, 0, (bx_address)0, (bx_address)next, (Bit8u*)at, &cb, &op);

	if( cb != NULL ) {
		if (insn.prefixes)
		{
			Byte prefix_byte = *((Byte*)mm_->map(pc));

			switch(prefix_byte)
			{
				case 0xF0:	// LOCK
					{
						(this->*cb)(&insn, &op, bb);
						next += insn.ilen; 
						break;
					}
				case 0xF2:	// REPNZ
					{
						hasRep = true;
						repFlag = 1;
						next += 1;
						break;
					}

				case 0xF3:	// REP
					{
						hasRep = true;
						repFlag = 2;
						next += 1;
						break;
					}
				case 0x65:
					{
						segOver = true;
						segReg = IA32ProcessorState::GS;
						(this->*cb)(&insn, &op, bb);
						next += insn.ilen; 
						break;
					}
				case 0x66:
					{
						//op_size = HALFWORD;
						(this->*cb)(&insn, &op, bb);
						next += insn.ilen; 
						break;
					}
				case 0x3E:
					{
						// SEG = DS
						(this->*cb)(&insn, &op, bb);
						next += insn.ilen; 
						break;
					}
				case 0x2E:
					{
						// SEG = CS
						(this->*cb)(&insn, &op, bb);
						next += insn.ilen; 
						break;
					}
			}
		}
		else
		{
			(this->*cb)(&insn, &op, bb);
			next += insn.ilen; 
		}
	}
	else {
		printf("Unimplemented callback!\n");
		printf("The source addr is 0x%x!\n", (Word)next);
		printf("The opcode is 0x%2x,prefix%2d,mod %2x!\n", (Byte)insn.b1,insn.prefixes,insn.modrm);
		exit(-1);
	}

	return next;
}
